TypeScript
/Advanced
Generic Constraints
Definition
Using the `extends` keyword within a generic type declaration to restrict the kinds of types that can be passed to a generic parameter.
Explain Like I'm New
Generics are great, but sometimes they are TOO flexible. If you build a generic function that prints the `.length` of an item, you want to allow Strings and Arrays, but NOT Numbers (numbers don't have a `.length` property). A Constraint acts as a bouncer, saying: 'I don't care what exact type you are, but you MUST at least have a .length property.'
Real World Example
Writing a generic function that updates a database record. The function takes any object, but it CONSTRAINS the object to ensure it MUST have an `id: string` property so the database knows what to update.
Common Use Cases
- •Restricting overly broad generics
- •Ensuring objects have required baseline properties
Interactive Example
// Define the baseline requirement interface HasLength { length: number; } // T can be anything, AS LONG AS it has a 'length' property of type number function logLength<T extends HasLength>(arg: T): void { console.log("Length is:", arg.length); } // Valid: Strings have .length logLength("Hello World"); // Valid: Arrays have .length logLength([1, 2, 3]); // Valid: Objects with a manual length property logLength({ id: 1, length: 10 }); // ERROR: Argument of type 'number' does not satisfy constraint 'HasLength'. // logLength(55);
Interview Questions
basic
- What keyword is used to constrain a generic?
intermediate
- What happens if you don't constrain a generic when accessing properties?
advanced
- Can you constrain a generic to be a specific primitive, like a string or number?