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.