CPCODELAB
TypeScript

Generic Constraints

8 min read

Generic Constraints

Sometimes you need to constrain what types a generic parameter can accept. The extends keyword adds constraints — the type parameter must be assignable to the constraint.

ts
// T must have a 'length' property
function longest<T extends { length: number }>(a: T, b: T): T {
  return a.length >= b.length ? a : b;
}

longest("hello", "world");  // string
longest([1, 2], [3]);       // number[]
longest(10, 20);            // Error — number has no 'length'

A common pattern is constraining to keyof another type parameter. This ensures you can only access properties that actually exist on the object.

ts
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { id: 1, name: "Alice", email: "a@b.com" };
const name = getProperty(user, "name");  // string
const id   = getProperty(user, "id");    // number
getProperty(user, "phone");             // Error — not a key of user

Use extends constraints to express intent: "this function works with any T, as long as T looks like X." This is the core of writing reusable, type-safe utility code — a pattern used throughout libraries like React, Zod, and Prisma.

Ready to test yourself?
Practice TypeScript— quiz & coding exercises