Generic Constraints
Constraining type parameters with extends and adding default type parameters for ergonomic APIs.
A constraint tells TypeScript what a generic value must support. The implementation can then use that shape safely.
extends limits T to values with the required members.
function longest<T extends { length: number }>(a: T, b: T): T {
return a.length >= b.length ? a : b;
}
console.log(longest("short", "longer"));
console.log(longest([1, 2], [3, 4, 5]));
function withId<T extends object>(item: T, id: string): T & { id: string } {
return { ...item, id };
}Default type parameters let callers omit a type argument when a sensible fallback exists.
interface ApiResponse<T = unknown> {
data: T;
status: number;
message: string;
}
const raw: ApiResponse = { data: null, status: 200, message: "OK" };
const typed: ApiResponse<{ id: string; name: string }> = {
data: { id: "1", name: "Ada" },
status: 200,
message: "OK",
};In production
Constrain early: <T extends object>, <T extends { id: string }>, or
<T extends keyof Model>. A constrained generic is usually clearer than an
unconstrained generic followed by casts inside the function.
Enjoyed this? Get more software craft delivered to your inbox.