Course outline · 0% complete

0/26 lessons0%

Course overview →

Constraints: extends for Type Parameters

lesson 6-3 · ~11 min · 20/26

When "any type" is too broad

Inside firstOf<T>, you could not do much with a T: it might be anything, so the compiler allows almost nothing on it. Suppose you want the longer of two values by their .length. Plain <T> fails, a.length is not known to exist.

A constraint narrows which types are allowed to fill the slot:

function longest<T extends { length: number }>(a: T, b: T): T {
  return a.length >= b.length ? a : b;
}

T extends { length: number } means "any type that has a numeric length property". Strings qualify, arrays qualify, { length: 5 } qualifies, numbers do not. Inside the body .length is now safe, and each call still returns the precise input type, not a vague "something with length".

Code exercise · typescript

Run it, strings and arrays both satisfy the constraint. Then try longest(10, 20) and read the error, numbers have no length.

Code exercise · typescript

Constraints shine on arrays of objects. Any element type with a numeric id satisfies T extends { id: number } — extra properties are welcome, that is structural typing from lesson 3-1. Run it, then try ids([{ name: "pen" }]) and read the error about the missing id.

Quiz

In function pick<T extends { id: number }>(items: T[]): T, which argument is rejected?

Code exercise · typescript

Your turn. Write describeLength<T extends { length: number }>(value: T): string returning "length " + value.length. Print it for the string "typescript" and for the array [true, false].