Suggest an editImprove this articleRefine the answer for “What does infer mean in TypeScript?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`infer`** declares a new type that TypeScript tries to infer from type `T` when `T` matches a certain pattern inside a conditional type, for example `T extends SomeType<infer U> ? U : DefaultType`. **Key point:** `infer` only works inside `extends`, you can declare several `infer` variables at once, and it is exactly what built-in utilities like `ReturnType<T>` are built on.Shown above the full answer for quick recall.Answer (EN)Image## Syntax ```javascript T extends SomeType<infer U> ? U : DefaultType ``` - `infer U` is a **declaration of a new type** `U` that TypeScript will try to **infer** from type `T` if `T` matches the pattern `SomeType<...>`. - If it can be inferred, `U` is returned. - If not, the branch after `:` is used. --- ## Example 1: Extracting a type from `Promise` ```javascript type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; type A = UnwrapPromise<Promise<string>>; // string type B = UnwrapPromise<number>; // number ``` > Here `infer U` says: "if `T` is `Promise<X>`, infer `X`". --- ## Example 2: Extracting the type of array elements ```javascript type ElementType<T> = T extends (infer U)[] ? U : T; type A = ElementType<string[]>; // string type B = ElementType<number[]>; // number type C = ElementType<boolean>; // boolean ``` `infer U` lets you "unwrap" the type of the array's elements. --- ## Example 3: Extracting a function argument's 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>; // string ``` > If `T` is a function, `infer U` pulls 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>; // boolean ``` > This is exactly how the built-in utility type `ReturnType<T>` is implemented in TypeScript. --- ## Example 5: Multiple `infer` inferences ```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]>; // 3 ``` --- ## Example 7: Unwrapping nested types (nested generics) ```javascript type DeepUnwrap<T> = T extends Promise<infer U> ? DeepUnwrap<U> : T; type A = DeepUnwrap<Promise<Promise<string>>>; // string ``` --- ## How this works logically `infer` operates **inside a conditional type**: - It checks whether `T` matches a specific structure (`extends Pattern`). - If it does, TypeScript "substitutes" concrete types in place of `infer U`. - Those inferred types can be used on the right-hand side of the expression (`? ... : ...`). --- ## Important limitations 1. `infer` **only works inside** `extends` (it cannot be used on its own). 2. You can declare **several** `infer` variables. 3. TypeScript can **infer a union** of types if the condition matches several shapes. --- ## Summary | What it does | Example | Result | |---|---|---| | Extracts a 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 |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.