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 userUse 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