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
,便于记忆。 - 如果一个值是联合类型,那么只能访问联合类型的共有属性或方法。