天天看點

Ts extends 泛型限制extends 泛型限制

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

'no'

,這是因為 Duck 沒有類型為

string

occupation

屬性,類型

Duck

不滿足類型

Human

的類型限制。是以,

A extends B

,是指類型

A

可以

配置設定給

類型

B

,而不是說類型A是類型B的子集,了解extends在類型三元表達式裡的用法非常重要。
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前面的參數是一個泛型類型,當傳入該參數的是聯合類型,則使用

配置設定律

計算最終的結果。配置設定律是指,

将聯合類型的聯合項拆成單項

,分别代入條件類型,然後将每個單項代入得到的結果再聯合起來,得到最終的判斷結果。

繼續閱讀