TypeScript 映射類型
TypeScript 會將一些好用的工具類型納入基準庫中,方便開發(fā)者直接使用,本節(jié)介紹的映射類型就是這樣的工具類型。
對這種工具類型,我們不只要知道使用方法,還要了解其實現(xiàn)功能的本質(zhì)。本節(jié)我們會從源碼進行分析,逐步掌握。
1. 慕課解釋
映射類型可以將已知類型的每個屬性都變?yōu)榭蛇x的或者只讀的。
2. Readonly 與 Partial 關鍵字
先來看這樣一個任務:將 Person 接口的每個屬性都變?yōu)榭蛇x屬性或者只讀屬性。
interface Person{
name: string
age: number
}
type PersonOptional = Partial<Person>
type PersonReadonly = Readonly<Person>
代碼解釋:
第 6 行,通過 Partial<Person>
這樣的語法格式得到類型別名 PersonOptional
,等價于:
type PersonOptional = {
name?: string
age?: number
}
第 7 行,通過 Readonly<Person>
這樣的語法格式得到類型別名 PersonReadonly
,等價于:
type PersonReadonly = {
readonly name: string
readonly age: number
}
3. 兩個關鍵字的源碼分析
來看它們的實現(xiàn)源碼:
type Readonly<T> = {
readonly [K in keyof T]: T[K]
}
type Partial<T> = {
[K in keyof T]?: T[K]
}
源碼就使用了映射類型的語法 [K in Keys]
,來看這個語法的兩個部分:
- 類型變量
K
:它會依次綁定到每個屬性,對應每個屬性名的類型。 - 字符串字面量構成的聯(lián)合類型的
Keys
:它包含了要迭代的屬性名的集合。
我們可以使用 for...in
來理解,它可以遍歷目標對象的屬性。
接下來繼續(xù)分析:
Keys
,可以通過keyof
關鍵字取得,假設傳入的類型是泛型T
,得到keyof T
,即為字符串字面量構成的聯(lián)合類型("name" | "age"
)。[K in keyof T]
,將屬性名一一映射出來。T[K]
,得到屬性值的類型。
已知了這些信息,我們就得到了將一個對象所有屬性變?yōu)榭蛇x屬性的方法:
[K in keyof T]?: T[K]
進而可得:
type Partial<T> = {
[K in keyof T]?: T[K]
}
Readonly<T>
和 Partial<T>
都有著廣泛的用途,因此它們與 Pick
一同被包含進了 TypeScript 的標準庫里:
type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}
interface User {
id: number
age: number
name: string
}
type PickUser = Pick<User, 'id'>
代碼解釋:
最后一行,就相當于 type PickUser = { id: number }
。
4. 小結
映射類型的語法是 [K in Keys]
,比較簡單,但是由此我們分析了幾個 TypeScript 標準庫中好用的工具類型。TypeScript 中工具類型有很多,感興趣的同學可以深入了解一下。