Lessons · TypeScript · extends: what a generic must have
A generic with a requirement
function len<T extends { length: number }>(x: T) accepts any T that has a numeric length: strings and arrays yes, numbers no.
Hone is a place to practise programming. This is one of its lessons, written out in full and free to read without an account.
What it is for
A generic with no constraint knows nothing about T, so x.length is an error inside the function. The constraint is what lets the body compile and still keeps the caller's exact type.
How to think about it
Ask what the function needs from T, write that as a shape after extends, and let everything with that shape in. Keep the shape minimal so more types qualify.
Worked example
function sizeOf<T extends { length: number }>(x: T): number { return x.length; }T can be anything with a numeric length.sizeOf("abc"); sizeOf([1, 2]);Strings and arrays qualify.sizeOf(42);Error: a number has no length.
Your turn
Constrain T to arrays.
function head<T unknown[]>(xs: T) { return xs[0]; }Solve one with the compiler running
The trap
Without a constraint, T is anything, and x.length is an error inside the function. The constraint is what makes the body compile.