thecodex.expert · The Codex Family of Knowledge
TypeScript

Generic Constraints

An unconstrained generic T could be anything at all — TypeScript won’t even let you access .length on it until you’ve constrained T to types that actually have one.

TypeScript 6.0 T extends SomeType Last verified:
Canonical Definition

Without a constraint, a generic type parameter T could be absolutely anything, so TypeScript only allows operations valid for every conceivable type — which in practice means almost nothing. Writing T extends SomeType restricts T to types assignable to SomeType, letting the function safely use SomeType's members on any value of type T. A common and useful constraint is keyof another generic, restricting one parameter's valid values to the property names of another.

The problem an unconstrained generic has

TypeScript has no idea T even has a .length property — T could be a number, a boolean, anything.

TypeScriptunconstrained.ts
function logLength<T>(item: T) {
    // console.log(item.length);   // COMPILE ERROR: T might not have a length property
}

Adding a constraint with extends

Now T is restricted to any type with a .length property, so accessing it is safe — while T can still be a string, an array, or any custom type that happens to have that shape.

TypeScriptconstrained.ts
interface HasLength {
    length: number;
}

function logLength<T extends HasLength>(item: T) {
    console.log(item.length);   // safe: T is guaranteed to have .length
}

logLength("hello");       // fine — string has .length
logLength([1, 2, 3]);      // fine — array has .length
// logLength(42);          // COMPILE ERROR: number doesn't have .length

keyof constraints: restricting to another type's keys

This is exactly how TypeScript's built-in Pick<T, K> and similar utility types constrain their key parameter — preventing a caller from passing a property name that doesn't actually exist on the object.

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

const user = { name: "Alice", age: 30 };
getProperty(user, "name");   // fine, returns string
// getProperty(user, "email"); // COMPILE ERROR: "email" is not a key of user

Sources

1
Microsoft. TypeScript Handbook, "Generic Constraints", typescriptlang.org/docs/handbook/2/generics.html.