extends 泛型限制
我們一般使用extends來繼承接口或者類,但是extends還可以用來泛型限制
function getCnames<T extends { name: string }>(entities: T[]):string[] {
return entities.map(entity => entity.cname)
}
比如,以上代碼對傳入的參數進行了限制,傳入的參數必須要有
name
這個屬性,否則就會出錯
條件類型與高階類型
extends
還有一大用途就是用來判斷一個類型是不是可以配置設定給另一個類型,這在寫進階類型的時候非常有用,舉個例子
type Lihua = {
name: string;
}
type Xiaoming = {
name: string;
}
type Bool = Lihua extends Xiaoming ? 'yes' : 'no'; // Bool => 'yes'
Lihua
和
Xiaoming
這兩個類型都有
name
這個屬性,而且類型是相同的,是以最後的結果是
yes
type Human = {
name: string;
occupation: string;
}
type Duck = {
name: string;
}
type Bool = Duck extends Human ? 'yes' : 'no'; // Bool => 'no'
而這段代碼中,
Duck
中并不存在
Human
中相關屬性,是以
Duck
不滿足限制條件,是以最後傳回的是
no
當我們給加上一個
Human
屬性,發現此時
occupation
是
Bool
,這是因為 Duck 沒有類型為
'no'
的
string
屬性,類型
occupation
不滿足類型
Duck
的類型限制。是以,
Human
,是指類型
A extends B
可以
A
類型
配置設定給
,而不是說類型A是類型B的子集,了解extends在類型三元表達式裡的用法非常重要。
B
type A1 = 'x' extends 'x' ? string : number; // string
type A2 = 'x' | 'y' extends 'x' ? string : number; // number
type P<T> = T extends 'x' ? string : number;
type A3 = P<'x' | 'y'> // string | number
P是帶參數T的泛型類型,其表達式和A1,A2的形式完全相同,A3是泛型類型P傳入參數
'x' | 'y'
得到的類型
對于使用extends關鍵字的條件類型(即上面的三元表達式類型),如果extends前面的參數是一個泛型類型,當傳入該參數的是聯合類型,則使用
計算最終的結果。配置設定律是指,
配置設定律
,分别代入條件類型,然後将每個單項代入得到的結果再聯合起來,得到最終的判斷結果。
将聯合類型的聯合項拆成單項