Learn the concept
Advanced Type Patterns
Complex constraints use multiple extends, conditional types, and recursive patterns. Variance determines how type parameters relate in subtyping: covariant (out), contravariant (in), invariant (both), and bivariant (neither). Understanding variance helps design safe generic APIs.
Complex Constraints:
T extends A & BT extends C ? D : ET extends { prop: T }Variance:
T in output position, subtype preservingT in input position, subtype reversingT in both positions, exact match requiredstrictFunctionTypes, function parameters are bivariant. With it enabled, function parameters are contravariant, but method declarations remain bivariant for compatibilityin/out variance annotations (TS 4.7+) to document intentPractical Implications:
// Multiple constraints
interface HasId { id: number; }
interface HasName { name: string; }
function merge<T extends HasId & HasName>(item: T) {
return { ...item, displayName: `${item.name} (${item.id})` };
}
// Constraint referencing other type parameter
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Conditional type in constraint
type ArrayElement<T> = T extends Array<infer E> ? E : never;
function first<T extends any[]>(arr: T): ArrayElement<T> {
return arr[0];
}
const n = first([1, 2, 3]); // number
const s = first(['a', 'b']); // string
// Recursive constraint (JSON-like values)
type JSONValue =
| string
| number
| boolean
| null
| JSONValue[]
| { [key: string]: JSONValue };
function toJSON<T extends JSONValue>(value: T): string {
return JSON.stringify(value);
}Using variance annotations to ensure data flows safely through covariant producers and contravariant consumers
Designing generic component/hook APIs where variance prevents unsafe type assignments
Using complex constraints to ensure plugins implement required interfaces with correct variance
Build an event bus using variance annotations where producers are covariant and consumers are contravariant
Implement a builder pattern with accumulating generic types that track selected fields