0

I have a TypeScript interface:

interface MyInterface {
  key1: string;
  key2: number;
  key3: SomeOtherType;
}

Then I have a class, which has (among other things) a private property that conforms to that interface:

class MyHandler {
  constructor(private myObject: MyInterface, ...otherThings) {}
}

I want to add an updateMyObject method to the class, which takes keyof MyInterface as the first argument and the value to update as the second argument.

class MyHandler {
  ...

  updateMyObject(key: keyof MyInterface, value: ???) {
    this.myObject[key] = value
  }
}

The interface has about 6 keys with some user-defined (or developer defined to be precise) types. I want to make sure that the user passes the correct type of argument when they call the update method. How can I ensure that? Is there a way to make sure, if a user passes key1 as the first argument, the second argument is of type string, for key3 it's SomeOtherType, and so on?

An obvious thing: If I go for implicit any type assignment, it shows me the error: Type 'any' is not assignable to type 'never'.

I have referred to this question, but what the answer suggests gives me the following error: Type 'string | number | ...' is not assignable to type 'never'.

It also makes me wonder, why is the type of this.myObject[key] never when I have assigned it a correct type at the time of declaration?

VaibhavJoshi
  • 355
  • 2
  • 15
  • *Technically* yes, but I see 2 problems with that approach. 1) The code readability and 2) In case of a bit more complex types, won't it cause a rabbit hole of `extends keyof typeof ...`? I guess both problems are related. – VaibhavJoshi Apr 30 '21 at 11:09
  • The `typeof` in the linked answer is incidental, since it was part of that question. For your code you would just use `MyInterface` and `keyof MyInterface`. – kaya3 Apr 30 '21 at 11:13
  • Yes, of course... I followed that from your comment on the answer, but the `K` refers to a generic type. My point is, when I call it, I'll have to call it something like this: `myHandler.updateMyObject('key', 'value')`, which results in a poor readability and some confusion, as the method name itself signifies that we are updating the given object. Is there any alternative to using generic types? – VaibhavJoshi Apr 30 '21 at 11:33
  • 1
    No, you don't have to explicitly provide type parameters when you call generic functions or methods, if the type parameters can be inferred from context. For this function they should always be inferred from context. Either way, you wouldn't need a generic type for `myObject` itself, `K extends keyof MyInterface` is the only type parameter, and `MyInterface` is hard-coded as the upper bound. – kaya3 Apr 30 '21 at 11:53

0 Answers0