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 matches SomeType<...>, then TypeScript extracts the type inside and binds it to U.
  • 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 into R.
  • 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.) !

By davs