Pattern-Match and Extract a Type
`infer`
`infer` declares a type variable inside a conditional type's pattern. Used to extract types out of complex shapes.
What you'll learn
- Read `infer` in conditional types
- Extract argument and return types from functions
- Pull array element types
infer X declares a type variable inside a conditional type’s
pattern. If the pattern matches, X is bound to the matched piece.
Extract Return Type
type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never;
type A = ReturnTypeOf<() => string>; // string
type B = ReturnTypeOf<(x: number) => User>; // User
type C = ReturnTypeOf<"not a function">; // never infer R binds R to whatever the function’s return type is.
Extract Parameter Types
type Params<T> = T extends (...args: infer A) => any ? A : never;
type P = Params<(a: string, b: number) => void>; // [string, number] Extract Array Element
type ElementOf<T> = T extends (infer U)[] ? U : never;
type E = ElementOf<string[]>; // string
type F = ElementOf<User[]>; // User Extract Promise’s Resolution
type Awaited<T> = T extends Promise<infer R> ? R : T;
type A = Awaited<Promise<string>>; // string
type B = Awaited<number>; // number (not a Promise, T flows through) A simplified Awaited<T> — the real one handles nested Promises.
Multiple infers
type FirstArg<T> = T extends (first: infer F, ...rest: any[]) => any ? F : never;
type LastArg<T> = T extends (...args: [...any[], infer L]) => any ? L : never; infer in different positions extracts different pieces.
Built-In Utilities Use It
The standard library is full of infer:
ReturnType<T>Parameters<T>ConstructorParameters<T>InstanceType<T>Awaited<T>
Most of them are 3–6 lines using conditional types and infer.
Up Next
The subtle behavior of conditional types when T is a union.
Distributive Conditionals →