TypeScript高級類型-Partial
預備知識:
先來看一下 Partial
類型的定義
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
假設我們有一個定義 user
的接口,如下
interface IUser {
name: string
age: number
department: string
}
經過 Partial
類型轉化後得到
type optional = Partial<IUser>
// optional的結果如下
type optional = {
name?: string | undefined;
age?: number | undefined;
department?: string | undefined;
}
那麼 Partial<T>
是如何實現類型轉化的呢?
-
遍歷入參
T
,獲得每一對key, value
-
將每一對中的
key
變爲可選,即添加?
-
希望得到的是由
key, value
組成的新類型
以上對應到 TypeScript
中是如何實現的呢?
對照最開始 Partial
的類型定義,能夠捕捉到以下重要信息
-
keyof
是幹什麼的? -
in
是幹什麼的? -
[P in keyof T]
中括號是幹什麼的? -
?
是將該屬性變爲可選屬性 -
T[P]
是幹什麼的?
keyof
keyof
,即 索引類型查詢操作符
,我們可以將 keyof
作用於泛型 T
上來獲取泛型 T
上的所有 public 屬性名
構成的 聯合類型
注意:"public、protected、private"修飾符不可出現在類型成員上
例如:
type unionKey = keyof IUser
// unionKey 結果如下,其獲得了接口類型 IUser 中的所有屬性名組成的聯合類型
type unionKey = "name" | "age" | "department"
in
我們需要遍歷 IUser
,這時候 映射類型
就可以用上了,其語法爲 [P in Keys]
- P:類型變量,依次綁定到每個屬性上,對應每個屬性名的類型
- Keys:字符串字面量構成的聯合類型,表示一組屬性名(的類型),可以聯想到上文
keyof
的作用
上述問題中 [P in keyof T]
中括號是幹什麼的?這裏也就很清晰了。
T[P]
我們可以通過 keyof
查詢索引類型的屬性名,那麼如何獲取屬性名對應的屬性值類型呢?
這裏就用到了 索引訪問操作符
,與 JavaScript 種訪問屬性值的操作類似,訪問類型的操作符也是通過 []
來訪問的,即 T[P]
,其中”中括號“中的 P
與 [P in keyof T]
中的 P
相對應。
例如
type unionKey = keyof IUser // "name" | "age" | "department"
type values = IUser[unionKey] // string | number 屬性值類型組成的聯合類型
最後我們希望得到的是由多個 key, value
組成的新類型,故而在 [P in keyof T]?: T[P];
外部包上一層大括號。
到此我們解決遇到的所有問題,只需要逐步代入到 Partial
類型定義中即可。
總結:
- 針對高級類型的編寫,我們可以嘗試將其以
JavaScript
的代碼方式表述出來,然後使用TypeScript
對其進行實現。 - 在每一個小步驟中遇到不懂的,可以結合最後的結果進行比對(比如本文中
Partial
的類型定義),發現問題點在哪裏,然後針對性查證並解決。