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
T
matchesSomeType<...>
, 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:
infer
only 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
X
should 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.) !