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];
}
}