🔷 TypeScript Q31 / 101

What is infer keyword?

AI-Powered Answer ✓ Answered

The 'infer' keyword in TypeScript is a powerful feature used within conditional types to extract or deduce a type from another type. It allows you to declare a type variable that can be inferred from the type being checked, enabling highly flexible and reusable type manipulations.

What is 'infer'?

'infer' is exclusively used within the 'extends' clause of a conditional type (T extends U ? X : Y). It introduces a type variable that can capture a type that appears in the 'U' part of the conditional type, allowing that captured type to be used in the 'X' (true) branch of the conditional type.

How 'infer' Works

When TypeScript evaluates a conditional type, if the type 'T' is assignable to the type 'U', and 'U' contains an 'infer' declaration, TypeScript attempts to deduce a type for the 'infer'red type variable. If successful, that deduced type is then available for use in the 'true' branch of the conditional type. If inference fails, or if 'T' is not assignable to 'U', the 'false' branch is taken.

Basic Example: Extracting Return Type of a Function

One of the most common uses for 'infer' is to extract the return type of a function type. TypeScript's built-in 'ReturnType<T>' utility type is implemented using 'infer'.

typescript
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

function greet(name: string): string {
  return `Hello, ${name}`;
}

function add(a: number, b: number): number {
  return a + b;
}

type GreetReturnType = MyReturnType<typeof greet>; // string
type AddReturnType = MyReturnType<typeof add>;     // number
type NotAFunctionReturnType = MyReturnType<number>; // any

In the MyReturnType<T> example: - T extends (...args: any[]) => infer R: We check if T is a function type. If it is, infer R attempts to capture the return type of that function into a new type variable R. - ? R: If the condition is true (T is a function and R is inferred), the type R is returned. - : any: If the condition is false (T is not a function or inference fails), any is returned.

Extracting Element Type from an Array

typescript
type ArrayElementType<T> = T extends (infer ElementType)[] ? ElementType : T;

type StringArray = ArrayElementType<string[]>; // string
type NumberArray = ArrayElementType<number[]>; // number
type MixedArray = ArrayElementType<(string | number)[]>; // string | number
type NonArray = ArrayElementType<boolean>;     // boolean

Here, infer ElementType captures the type of the elements within the array if T is an array type.

Extracting Promise Value Type

typescript
type PromiseValue<T> = T extends Promise<infer Value> ? Value : T;

type MyPromise = PromiseValue<Promise<string>>; // string
type AnotherPromise = PromiseValue<Promise<number[]>>; // number[]
type NotAPromise = PromiseValue<boolean>; // boolean

infer Value extracts the type that the Promise resolves to.

Key Takeaways

  • infer is used exclusively within conditional types (T extends U ? X : Y).
  • It declares a type variable (infer R) that TypeScript attempts to deduce from the type in the 'extends' clause.
  • The inferred type variable (R) is only available in the 'true' branch of the conditional type.
  • It is fundamental for creating powerful and generic type utilities that dynamically extract parts of other types.
  • Many of TypeScript's built-in utility types (e.g., ReturnType, Parameters, Awaited) leverage infer.