TypeScript Infer keyword Explained
What is infer keyword? What are the use cases?
The Infer
keyword can be perplexing and challenging to grasp. This article aims to provide a clear and straightforward explanation of this concept.
In the official documentation, infer is mentioned in the Conditional Type s section:
Within the
extends
clause of a conditional type, it is now possible to haveinfer
declarations that introduce a type variable to be inferred. Such inferred type variables may be referenced in the true branch of the conditional type. It is possible to have multipleinfer
locations for the same type variable.
If the above definition is as clear as mud to you, don’t worry, you’re not alone.
What is infer keyword?
The infer keyword allows you to deduce a type from another type within a conditional type. Here’s an example:
1 | _type_ UnpackArrayType<T> = T _extends_ (infer R)[] ? R: T;_type_ t1 = UnpackArrayType<number[]>; // t1 is number |
UnpackArrayType
is a conditional type. It is read as “If T is a sub-type of _(infer R)[]_
, return _R_
. Otherwise, return _T_
”.
For type alias t1
, the condition in UnpackArrayType
is true because number[]
matches with (infer R)[]
. As the result of the infer process, the type variable R
is inferred to be number
type, and returned from the true branch. Infer is there to tell the compiler that a new type variable R is declared within the scope of UnpackArrayType.
1 | _type_ t2 = UnpackArrayType<string>; //t2 is string |
For t2
, the condition in UnpackArrayType
is false, as the string type does not match with(infer R)[]
, so it is returned as string
.
Scope
Infer
keyword only works within a conditional type. You will get an error if you try to use it outside the conditional type.
Here are a few examples of the infer
keyword use cases.
Case 1: Extract type from Promise
1 | type unboxFromPromise<T> = T extends Promise<infer R>? R : T; |
In this example, we can deduce the result of promiseType
from the equation:_Promise<string[]> = Promise<infer R>_
Thus the promiseType
is string[].
Case 2: Extract function return type
1 | type functionReturn<T> = T extends (…args: string[]) => infer R? R: T; |
The functionReturn
will return the function return type asR
type variable if the type passed in matches a function signature. If the condition is false, then T
is returned.
Case 3: Extract multiple candidates
In TypeScript documentation, it says
multiple candidates for the same type variable in co-variant positions causes a union type to be inferred
1 | type unboxFromObject<T> = T extends {a: infer R; b: infer R} ? R: never; |
In other words, when a type is inferred for several values, the result is a union type. In the above example, the result is “string | number
”.
multiple candidates for the same type variable in contra-variant positions causes an intersection type to be inferred.
1 | type unboxFromObjectFunctions<T> = T extends { a: (x: infer U) => void; b: (x: infer U) => void }? U: never;type r2= unboxFromObjectFunctions<{ a: (x: string) => void; b: (x: number) => void }>; // string & number |
Use Infer Within a Recursive conditional type
The following example is a more advanced example of using infer with a recursive conditional type to flatten a nested array. Please note that the recursive type is only supported from TypeScript version 4.1.0 onwards.
1 | type Flatten<T extends readonly unknown[]> = T extends unknown[] ? _Flatten<T>[] : readonly _Flatten<T>[]; |
I like the above example, as it shows how the TypeScript types can be used to write concise and self-explanatory code.
Summary
Infer keyword isn’t something you need to use daily, but it is widely used in advanced Utility types. Understanding it will help you use Utility types properly.
This is the 3rd article of my “TypeScript Types” series, and you can find the other two articles below.
TypeScript’s Record Type Explained
I hope you have found this useful. Happy programming!
- Title: TypeScript Infer keyword Explained
- Author: Sunny Sun
- Created at : 2021-06-01 00:00:00
- Updated at : 2024-08-16 19:46:32
- Link: http://coffeethinkcode.com/2021/06/01/typescript-infer-keyword-explained/
- License: This work is licensed under CC BY-NC-SA 4.0.