๐ŸŽ“ A1Learner
๐Ÿ”
0 of 42 lessons completed

TypeScript keyof with Generics

The keyof operator reads the keys of an object type and builds a union of string literals from them. Combined with a constraint, it limits a key argument to keys that truly exist.

keyof builds the key union

ProductKey is the union of the three member names of Product. Both assignments below are members of that union.

interface Product {
  id: number;
  name: string;
  stock: number;
}
type ProductKey = keyof Product;
const product: Product = { id: 1, name: 'Pen', stock: 4 };
const firstKey: ProductKey = 'name';
const secondKey: ProductKey = 'stock';
console.log(product[firstKey]);
console.log(product[secondKey]);

The getProperty pattern returns T[K]

The key parameter is constrained by keyof T, and the return type T[K] follows the chosen key. A name lookup returns a string and a stock lookup returns a number.

function getProperty<T, K extends keyof T>(item: T, key: K): T[K] {
  return item[key];
}
const product = { id: 1, name: 'Pen', stock: 4 };
console.log(getProperty(product, 'name'));
console.log(getProperty(product, 'stock'));

A key outside the union is refused

The product has no price member, so the literal is outside the key union. The call fails the compile with the union named in the message.

function getProperty<T, K extends keyof T>(item: T, key: K): T[K] {
  return item[key];
}
const product = { id: 1, name: 'Pen', stock: 4 };
console.log(getProperty(product, 'price'));

Example

function pickValues<T, K extends keyof T>(item: T, keys: K[]): T[K][] {
  return keys.map((key) => item[key]);
}
const product = { id: 1, name: 'Pen', stock: 4 };
console.log(pickValues(product, ['name', 'stock']));
console.log(pickValues(product, ['id']));

Key points

  • keyof Product produces the union 'id' | 'name' | 'stock' for the product type.
  • A variable typed by keyof accepts only the listed key literals.
  • The pattern K extends keyof T ties the key parameter to the object parameter.
  • The indexed access type T[K] gives the exact type of the chosen member.
  • A key outside the union is refused at the call, before any code runs.

In this example, the keys array holds only members of the keyof union, and each picked value keeps its member type through T[K]. One call mixes a string and a number value in a single result array.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท TypeScript Playground

Exercise

What type does keyof Product give for a product with id, name and stock?