Reputation: 15248
I have, many times, tried to implement generic functions that extract properties from an object. The code underneath in Typescript it returns string | number, though I wanted it to know that it will return a string or a number specifically. In plain JS I would know that the code underneath would return a string and react accordingly, so I hope any light to how this can be solved in Typescript can be shed.
interface Person {
name: string;
age: number;
}
const getPropertyByKey = (
person: Person
) => (
key: keyof Person
) => person[key];
const person = {
name: 'Thomas',
age: 32
};
const property = (person)('name'); // Should realise it is a string
Upvotes: 0
Views: 1093
Reputation: 51886
Make the partial function generic and it will be able to infer the type of the return value based on the specific string value of key
.
interface Person {
name: string;
age: number;
}
const getPropertyByKey = (
person: Person
) => <K extends keyof Person>(
key: K
) => person[key];
const person = {
name: 'Thomas',
age: 32
};
const property = getPropertyByKey(person)('name');
Upvotes: 2
Reputation:
This should work for your example
function prop<T, V extends keyof T>(val: T, key: V): T[V] {
return val[key];
}
const prop1 = prop({ id: 1, name: 'Pete' }, 'id'); // number
const prop2 = prop({ id: 1, name: 'Pete' }, 'name'); // string
Upvotes: 1
Reputation: 1326
I guess you have to tell TS what you want. It's a bit more verbose:
const getPropertyByKey = (person: Person) => (key:any) =>
"number" === typeof key ? person["age"] : person["name"];
Upvotes: 0