I have the following code:
interface Person {
name: string;
age: number;
}
class Store<T, K extends keyof T> {
constructor(private obj: T) { }
get(key: K): T[typeof key] {
return this.obj[key];
}
}
const person: Person = {
name: 'John',
age: 99
};
const store = new Store(person);
const value = store.get('name');
value type shows:
const value = store.get('name');
// ^^^^^ value: string | number
How to infer the value type of an object given its key as an argument in a class method?
I want value to be properly typed as string in this case. How to achieve this?
CodePudding user response:
The get function itself needs to be generic so it can use the type of the argument. This allows it return a specific key from T like T[K].
And the K generic on the class now no longer makes sense. keyof T would be the same thing anywhere in that class, so you can remove it completely.
Put another way Store as a class doesn't think any one key is special, so it doesn't need a generic for that. But the get method needs to get one specific key, so the type system needs to know which specific key, so you need a generic there.
class Store<T> {
constructor(private obj: T) { }
get<K extends keyof T>(key: K): T[K] {
return this.obj[key];
}
}
