A generic type parameter can be constrained with `extends`, limiting which types are allowed and unlocking property access that would otherwise be unsafe.
ts
interface HasId { id: string; }
function findById<T extends HasId>(items: T[], id: string): T | undefined {
return items.find(item => item.id === id);
}
interface Token extends HasId { symbol: string; }
const tokens: Token[] = [{ id: "1", symbol: "ETH" }];
findById(tokens, "1"); // T inferred as TokenBecause `T extends HasId`, the compiler allows `item.id` inside the function body. Without the constraint, `T` could be anything, and `.id` wouldn't be guaranteed to exist. `keyof` is often combined with constraints, e.g. `function pick<T, K extends keyof T>(obj: T, key: K): T[K]`.