Skip to main content

infer in conditional types

The infer keyword is used within conditional types to infer (extract) type information. It allows you to capture and use types that are matched within a conditional type.

type InferredType<T> = T extends infer U ? U : never;

Here, U is a type variable that is inferred from T.

Usages

infer is particularly useful when working with complex types, such as function types, promise types, or nested object types.

A lot of useful built-in helper types in TypeScript are actually built using infer under the hood.

Inferring return types

You can use infer to extract the return type of a function:

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

type Func = (x: number) => string;
type FuncReturnType = MyReturnType<Func>;
// ^ FuncReturnType: string

Inferring Promise return types

You can extract the type wrapped by a Promise:

type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

type PromiseType = UnwrapPromise<Promise<number>>; // number

Inferring array element Types

You can extract the element type of an array:

type ArrayElement<T> = T extends (infer U)[] ? U : never;

type NumberArray = ArrayElement<number[]>; // number

Multiple inferences

You can use multiple infer keywords in a single conditional type:

type FirstAndLast<T extends any[]> = T extends [infer F, ...any[], infer L] ? [F, L] : [never, never];

type FL = FirstAndLast<[1, 2, 3, 4]>; // [1, 4]

The infer keyword, combined with conditional types, provides a powerful way to perform type-level programming in TypeScript, enabling complex type transformations and pattern matching on types.

Exercise 8.1

Use infer with conditional types to implement utility types.

Exercise 8.2

Use infer with conditional types to implement advanced type utilities.