TypeScript ยท Chapter 22 of 44

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.

Syntax
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.

Example 1 (typescript)
function logLength<T extends { length: number }>(item: T): T {
  console.log(item.length);
  return item;
}
logLength("hello");
logLength([1, 2, 3]);
Output
5
3

Both strings and arrays have a length property, so they satisfy the constraint.

Example 2 (typescript)
interface HasId {
  id: number;
}
function printId<T extends HasId>(item: T): void {
  console.log(`ID: ${item.id}`);
}
printId({ id: 7, name: "Box" });
Output
ID: 7

The 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.
๐Ÿ’ก Note: Constraints strike a balance between flexibility and safety when writing generic code.

๐Ÿ“ Quick Quiz

1. How do you constrain a generic type parameter?

2. What does `<T extends { length: number }>` require?

3. Why use generic constraints?