TypeScript 交叉型別

admin發表於2019-04-24

交叉型別(Intersection Types)可以將現有的多種型別疊加到一起成為一種型別。

也就是說它包含了所有型別的特性,程式碼例項如下:

[typescript] 純文字檢視 複製程式碼
A & B & C

上面的交叉型別同時具有A、B和C三種型別的成員。

較多在混入(mixins)或其它不適合典型物件導向模型的地方看到交叉型別的使用。

程式碼例項如下:

[typescript] 純文字檢視 複製程式碼
function extend<T, U>(first: T, second: U): T & U {
  let result = <T & U>{};
  for (let id in first) {
    (<any>result)[id] = first[id];
  }
  for (let id in second) {
    if (!result.hasOwnProperty(id)) {
      (<any>result)[id] = (<any>second)[id];
    }
  }
  return result;
}

上面的程式碼相對比較簡單,可能下面這一段程式碼會產生疑問:

[typescript] 純文字檢視 複製程式碼
(<any>result)[id] = first[id];

既然result已經被斷言為交叉型別,那麼first所具有的屬性result都是具有的。

為什麼還要將result斷言為Any型別呢,因為交叉型別可能導致型別衝突。

看如下程式碼例項:

[typescript] 純文字檢視 複製程式碼
interface T1 {
  a: boolean;
  b: string;
}
 
interface T2 {
  a: boolean;
  b: number;
}
 
type T = T1 & T2;
 
type Ta = T['a']; // boolean
type Tb = T['b']; // string & number
 
declare const t: T;
declare const t1: T1;
t['b'] = t1['b'];

上面的程式碼中,T1和T2介面中,b屬性型別衝突,那麼最終b屬性型別為交叉型別string & number,同時string型別或者number型別無法賦值給交叉型別string & number,最終導致報錯。為了解決這個問題,可以將resut再斷言為Any型別,這樣result所有屬性均為Any型別,那麼賦值就不會報錯了。

相關文章