TypeScript infer 關鍵字
本節要介紹的 infer 關鍵字有些難理解,我們來通過一個類比來幫助理解。
語句 let num 中,通過 let 來聲明了一個變量,那怎樣聲明一個不確定的類型變量呢? 答案是使用 infer 關鍵字,infer R 就是聲明了一個類型變量 R。
1. 慕課解釋
在條件類型表達式中,可以在 extends 條件語句中使用 infer 關鍵字來聲明一個待推斷的類型變量。
2. 通過 ReturnType 理解 infer
infer 相對比較難理解,我們先看下 TypeScript 一個內置工具類型 ReturnType 。
ReturnType<T>– 獲取函數返回值類型。
const add = (x:number, y:number) => x + y
type t = ReturnType<typeof add> // type t = number
代碼解釋:
通過 ReturnType 可以得到函數 add() 的返回值類型為 number 類型。但要注意不要濫用這個工具類型,應盡量多的手動標注函數返回值類型。
來看一下 ReturnType 的實現源碼:
/**
* Obtain the return type of a function type
*/
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any
infer 的作用是讓 TypeScript 自己推斷,并將推斷的結果存儲到一個類型變量中,infer 只能用于 extends 語句中。
再來看 ReturnType 的實現:如果 T 滿足約束條件 (...args: any) => any,并且能夠賦值給 (...args: any) => infer R,則返回類型為 R,否則為 any 類型。
繼續看幾個例子:
type T0 = ReturnType<() => string> // string
type T1 = ReturnType<(s: string) => void> // void
type T2 = ReturnType<<T>() => T> // unknown
代碼解釋:
分別可以得到 type T0 = string type T1 = void type T2 = unknown,只要滿足約束條件 (...args: any) => any,TypeScript 推斷出函數的返回值,并借助 infer 關鍵字將其儲存在類型變量 R 中,那么最終得到返回類型 R。
3. 借助 infer 實現元組轉聯合類型
借助 infer 可以實現元組轉聯合類型,如:[string, number] -> string | number
type Flatten<T> = T extends Array<infer U> ? U : never
type T0 = [string, number]
type T1 = Flatten<T0> // string | number
代碼解釋:
第 1 行,如果泛型參數 T 滿足約束條件 Array<infer U>,那么就返回這個類型變量 U。
第 3 行,元組類型在一定條件下,是可以賦值給數組類型,滿足條件:
type TypeTuple = [string, number]
type TypeArray = Array<string | number>
type B0 = TypeTuple extends TypeArray ? true : false // true
第 4 行,就可以得到 type T1 = string | number。
4. 小結
infer 理解起來比較抽象,一定要親手寫一下本節中的例子。借助條件類型的 infer 關鍵字來推斷類型,可以實現一些比如聯合類型轉交叉類型、聯合類型轉元組的操作,有興趣的可以了解一下。
一飛同學 ·
2025 imooc.com All Rights Reserved |