infer in TypeScript β itβs one of the most powerful(but sometimes confusing) features.
π What is infer?
The infer keyword is used inside a conditional type to declare a new type variable that TypeScript will try to “infer” (deduce) from the type expression.
In plain words:
infer= βlet TypeScript figure this type out here, and Iβll give it a name so I can use it later.β
β‘ Syntax
T extends SomeType<infer U> ? U : Fallback
- If
TmatchesSomeType<...>, then TypeScript extracts the type inside and binds it toU. - Otherwise, the fallback branch is used.
π Simple Examples
1. Extracting an array element type
type ElementType<T> = T extends (infer U)[] ? U : never;
type A = ElementType<string[]>; // string
type B = ElementType<number[]>; // number
type C = ElementType<boolean>; // never (not an array)
Here, infer U captures the element type of the array.
2. Extracting function return type
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type A = MyReturnType<() => number>; // number
type B = MyReturnType<(x: string) => boolean>; // boolean
type C = MyReturnType<string>; // never
Here, infer R captures the return type of the function.
3. Extracting function parameter type
type FirstArg<T> = T extends (arg: infer P, ...args: any[]) => any ? P : never;
type A = FirstArg<(x: string, y: number) => void>; // string
type B = FirstArg<() => void>; // never
Here, infer P captures the type of the first parameter.
π§ How it works under the hood
Think of infer like a pattern match for types:
inferonly appears in a conditional type (extends ? :).- When TypeScript sees
infer R, it tries to unify the given type with the pattern, extracting what fits intoR. - If successful, you can use that inferred type in the true branch.
- If not, the false branch is chosen.
π Why is infer powerful?
Because you can extract pieces of types dynamically, without manually writing them.
This is how many utility types (like ReturnType, Parameters, InstanceType, etc.) are built.
β
Summary of infer:
- Used only in conditional types.
- Introduces a temporary type variable (
infer X). - TypeScript automatically deduces what
Xshould be if the pattern matches. - Lets you extract parts of complex types (array elements, function returns, parameters, etc.).
Build your own custom utility types step by step using infer (like Parameters<T>, ConstructorArgs<T>, etc.) !
