What does infer mean in TypeScript?
Syntax
javascript
T extends SomeType<infer U> ? U : DefaultTypeinfer Uis a declaration of a new typeU, which TypeScript will try to infer from the typeT, ifTmatches the patternSomeType<...>.- If it can be inferred,
Uis returned. - If it cannot, the branch after
:is used.
Example 1: Extracting the type from Promise
javascript
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type A = UnwrapPromise<Promise<string>>; // string
type B = UnwrapPromise<number>; // numberHere
infer Usays: "ifTisPromise<X>, inferX".
Example 2: Extracting the array element type
javascript
type ElementType<T> = T extends (infer U)[] ? U : T;
type A = ElementType<string[]>; // string
type B = ElementType<number[]>; // number
type C = ElementType<boolean>; // booleaninfer U lets you "unwrap" the type of array elements.
Example 3: Extracting a function's argument type
javascript
type ArgType<T> = T extends (arg: infer U) => any ? U : never;
type A = ArgType<(x: number) => void>; // number
type B = ArgType<(x: string) => void>; // stringIf
Tis a function,infer Upulls out the type of its argument.
Example 4: Extracting a function's return type
javascript
type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never;
type A = ReturnTypeOf<() => string>; // string
type B = ReturnTypeOf<(x: number) => boolean>; // booleanThis is exactly how the built-in
ReturnType<T>utility type is implemented in TypeScript.
Example 5: Multiple infer extractions
javascript
type FirstArgAndReturn<T> =
T extends (arg: infer A) => infer R ? [A, R] : never;
type Example = (x: string) => number;
type Result = FirstArgAndReturn<Example>; // [string, number]Example 6: Extracting types from tuples
javascript
type First<T> = T extends [infer F, ...any[]] ? F : never;
type Last<T> = T extends [...any[], infer L] ? L : never;
type A = First<[1, 2, 3]>; // 1
type B = Last<[1, 2, 3]>; // 3Example 7: Unwrapping nested types (nested generics)
javascript
type DeepUnwrap<T> =
T extends Promise<infer U> ? DeepUnwrap<U> : T;
type A = DeepUnwrap<Promise<Promise<string>>>; // stringHow this works logically
infer operates inside a conditional type:
- It checks whether
Tmatches a certain structure (extends Pattern). - If it does, TypeScript "substitutes" concrete types in place of
infer U. - These inferred types can be used on the right-hand side of the expression (
? ... : ...).
Important limitations
inferonly works insideextends(it cannot be used on its own).- You can declare several
infervariables. - TypeScript can infer a union of types if the condition matches several forms.
SUMMARY
| What it does | Example | Result |
|---|---|---|
Extracts the type from Promise | T extends Promise<infer U> ? U : T | "unwraps" the promise |
| Extracts an array element | T extends (infer U)[] ? U : T | gets the element type |
| Extracts a function argument | T extends (arg: infer A) => any ? A : never | gets the argument type |
| Extracts the return value | T extends (...args: any[]) => infer R ? R : never | gets the result type |
| Extracts from a tuple | T extends [infer F, ...any[]] ? F : never | the first element |
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.