Thomas Johansen
Thomas Johansen

Reputation: 15248

Return property from object with correct type using generic typing in typescript

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

Answers (3)

Patrick Roberts
Patrick Roberts

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');

Playground Link

Upvotes: 2

user13258211
user13258211

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

Sven
Sven

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

Related Questions