TypeScript Intermediate: Utility Types, Narrowing & Advanced Types

Lesson 5 of 7

Generic Constraints & Default Type Parameters

The beginner course's firstElement<T> worked for any T, but plenty of generic functions only make sense for types that have something specific about them. Constraints narrow what T is allowed to be.

TypeScript

T extends HasId doesn't mean inheritance the way a class extends does, it means "whatever T ends up being, it must have at least the shape of HasId." Inside the function, item.id is safe to access precisely because the constraint guarantees it exists, no matter which concrete type T turns out to be.

Constraining with keyof

A very common constraint ties a generic parameter to the keys of another generic parameter.

TypeScript

K extends keyof T means "K can only be one of T's actual property names," so getProperty can never be called with a key that doesn't exist, and its return type (T[K]) is exactly the type of that specific property, not a generic unknown.

Default type parameters

Generics can also supply a default, used when the caller doesn't specify one explicitly.

TypeScript

T = unknown means ApiResponse (with no type argument at all) still compiles, falling back to unknown for data, while callers that care can still specify exactly what they're returning.

NOTE

Constraints and defaults are how library-quality generic functions stay both flexible and safe, flexible enough to work with many types, safe enough that the compiler still catches misuse instead of silently allowing anything.

📝 Generic Constraints Quiz

Passing score: 70%
  1. 1.What does `T extends HasId` mean for a generic type parameter?

  2. 2.`K extends keyof T` restricts K to only the actual property names of T.

  3. 3.In `interface ApiResponse<T = unknown>`, `unknown` is the ____ type parameter, used when the caller supplies none.

  4. 4.Given `getProperty<T, K extends keyof T>(obj: T, key: K): T[K]`, what does the return type T[K] guarantee?