TypeScript 聯合類型
本節介紹聯合類型,它使用管道符 |
把多個類型連起來,表示它可能是這些類型中的其中一個。我們把 |
理解成 or
,這樣便于輕松記憶。
1. 慕課解釋
聯合類型與交叉類型很有關聯,但是使用上卻完全不同。區別在于:聯合類型表示取值為多種中的一種類型,而交叉類型每次都是多個類型的合并類型。
語法為:類型一 | 類型二
。
2. 簡單示例
聯合類型之間使用豎線 “|” 分隔:
let currentMonth: string | number
currentMonth = 'February'
currentMonth = 2
代碼解釋: 第 1 行,表示 currentMonth 的值可以是 string 類型或者 number 類型中的一種。
聯合類型的構成元素除了類型,還可以是字面量:
type Scanned = true | false
type Result = { status: 200, data: object } | { status: 500, request: string}
代碼解釋:
第 1 行,表示類型別名 Scanned
可以是 true
或者 false
兩種布爾字面量中的一種。
第 2 行,表示類型別名 Result
可以是 { status: 200, data: object }
或者 { status: 500, request: string}
兩個對象字面量中的一種。
3. 訪問聯合類型成員
如果一個值是聯合類型,那么只能訪問聯合類型的共有屬性或方法。
interface Dog {
name: string,
eat: () => void,
destroy: () => void
}
interface Cat {
name: string,
eat: () => void,
climb: () => void
}
let pet: Dog | Cat
pet!.name // OK
pet!.eat() // OK
pet!.climb() // Error
代碼解釋:
第 13 行,聲明變量 pet
為 Dog | Cat
聯合類型,那么變量 pet
可以訪問接口 Dog
和 接口 Cat
共有的 name 屬性和 eat() 方法。訪問接口 Cat
獨有的 climb()
方法是錯誤的。
4. 可辨識聯合
聯合類型的應用場景很多,我們在類型保護那一節介紹了大量的聯合類型的例子。
下面再介紹一個求不同圖形面積的綜合性實例:
interface Rectangle {
type: 'rectangle',
width: number,
height: number
}
interface Circle {
type: 'circle',
radius: number
}
interface Parallelogram {
type: 'parallelogram',
bottom: number,
height: number
}
function area(shape: Rectangle | Circle | Parallelogram) {
switch (shape.type) {
case 'rectangle':
return shape.width * shape.height
case 'circle':
return Math.PI * Math.pow(shape.radius, 2)
case 'parallelogram':
return shape.bottom * shape.height
}
}
let shape: Circle = {
type: 'circle',
radius: 10
}
console.log(area(shape))
代碼解釋:
第 18 行,函數 area()
的參數是一個 Rectangle | Circle | Parallelogram
聯合類型。
其中,每個接口都有一個 type 屬性
,根據其不同的字符串字面量類型引導到不同的 case 分支,這種情況我們稱之為『可辨識聯合(Discriminated Union)』。
5. 小結
本節介紹了高級類型中的聯合類型,下節開始介紹類型別名。需要記住的是:
- 把
|
理解成or
,便于記憶。 - 如果一個值是聯合類型,那么只能訪問聯合類型的共有屬性或方法。