iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 25
1
Modern Web

從零開始進入 JavaScript & TypeScript 的世界系列 第 25

第25天-交叉型別(Intersections Types)

  • 分享至 

  • xImage
  •  

之前學過 TypeSecript 的 Union Type 是屬於可以為多個型別中的一種就行,沒想到剛剛居然發現他還有一種型別是屬於多個型別的型別,也就是他不是其中一種,他是多種型別組合成的新型別。真是太神奇了!

我在第一次看到這個型別的時候,我覺的他好像有種多重繼承的感覺,因為他給的範例是這樣說的:

"Person & Serializable & Loggable" 這個型別會同時是 Person 和 Serializable 和 Loggable。 就是說這個類型的對象同時擁有了這三種類型的成員。

(From http://www.typescriptlang.org/docs/handbook/advanced-types.html#intersection-types)

範例中的 & 是 intersection types 的組合關鍵字, 也就是說 Person & Serializable & Loggable 是一個新的型別的意思。他就是屬於 Intersection Types。最少兩個,最多目前沒看到有文件說明有限制。

不過後來看其他的範例,感覺上比較像是合併型別的概念。例如下面這個例子:

type score = { score: number };
type getPass = { isPass: boolean };
type name = { name: string };

function methodAbc(value: score&getPass&name) {
  console.log(
      'You call methodAbc with parameter {' +
      'score:' + value.score +
      ', isPass:' + value.isPass +
      ', name:' + value.name + '}');
}

methodAbc({score: 99, isPass: true, name: 'Super'});
// 結果會是:You call methodAbc with parameter {score:99, isPass:true, name:Super}

語法:

Type1 & Type2 & Type3 & ... & TypeN

而我們在使用上可以把直接使用,例如:

function someMethod(var1: Type1, var2: Type2) : Type1 & Type2 {
  // other implementation
}

也可以宣告一個新型別:

type newTYpe =  Type1 & Type2 & ... & TypeN

也可以把新型別做合併成另一個新型別:

type TypeA = Type1 & Type2
type TypeB = Type3 & Type4

type typeNew =TypeA & TypeB

可能與不可能

在使用 intersection type 的時候,我們可以天馬型空的去創造任意的新型別,但是要小心別創造出不可能存在的新型別。這通常比較會發生在基本型別上面,對於物件型別比較少發生。因為通常基本型別比較單純,已經無法在拆分了,所以比較容易發生。

舉個例子來說,我們可以創造一個 文字布林 型別,但是,我們無法產生又是文字也是布林的值。

type StringAndBoolean = string & boolean;

function methodWithImpossibleParam( param: StringAndBoolean) {
  // some implementation
}

methodWithImpossibleParam("text"); // Error!!!
methodWithImpossibleParam(false); // Error

但對於物件型別來說,就如同最一開始的範例,使用物件型別,就有點像組合的概念,把裡面的東西通通合併在一起:

type Student = { name: string };
type Course = { score: number, courseName: string };

type StudentAndCourse = Student&Course;

let student101: StudentAndCourse = {
  name: 'Alex',
  score: 80,
  courseName: 'English',
};

如果 student101 在上面的範例中, name, scorecourseName 有少任一個屬性,就會編譯錯誤!所以,必須都要有才行。


上一篇
第 24 天-提高程式碼品質的樣板字串(Template String)
下一篇
第26天-Promise
系列文
從零開始進入 JavaScript & TypeScript 的世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言