TypeScript Generic Constraints
Sometimes a generic function needs to guarantee that the type it works with has certain properties, such as a `.length` property. Generic constraints let you specify these requirements with `extends`.
By constraining a generic type, you can safely access specific properties or methods inside the function, while still allowing the function to work with many different concrete types that satisfy the constraint.
function logLength<T extends { length: number }>(item: T): T {
console.log(item.length);
return item;
}Using extends for constraints
Writing `<T extends { length: number }>` means T must be some type that has a numeric length property, like arrays or strings, but not, for example, a plain number.
Constraining with interfaces
You can also constrain a generic to match a specific interface, ensuring any type passed in implements all the properties that interface requires.
function logLength<T extends { length: number }>(item: T): T {
console.log(item.length);
return item;
}
logLength("hello");
logLength([1, 2, 3]);5
3Both strings and arrays have a length property, so they satisfy the constraint.
interface HasId {
id: number;
}
function printId<T extends HasId>(item: T): void {
console.log(`ID: ${item.id}`);
}
printId({ id: 7, name: "Box" });ID: 7The constraint ensures item always has an id property, regardless of what other properties it has.
Key points
- Generic constraints use `extends` to require specific properties.
- Constraints let you safely access properties inside a generic function.
- A constraint can reference an object shape or an interface.
- Types that don't satisfy the constraint are rejected at compile time.
