文章快速索引:
1、TypeScript快速入门教程(一)、基础类型和变量声明
2、TypeScript快速入门教程(二)、面向对象知识(接口、类、抽象类)
3、TypeScript快速入门教程(三)、函数、范型使用
4、TypeScript快速入门教程(四)、联合类型 & 交叉类型 & 类型保护
联合类型
和交叉类型
其实在生活中是一个很常见的案例。
- 黄瓜,你说他是水果还是蔬菜呢?
- 番茄是属于水果还是属于蔬菜呢?
- 那么水果黄瓜呢?
其实我们单纯看黄瓜和番茄的话,其实既可以算是水果,也能算是蔬菜,其实就是场景决定的,我要做菜,它就是蔬菜,拿来生吃,就是水果呗。
基于以上的知识点,我们可以这样理解:
- 联合类型, 它的类型既可以是 A,也可以是B,伪代码表示的话,就是
A | B
- 交叉类型, 它的类型包含A的特点,也包含B的特点,伪代码表示的话,就是
A & B
根据上面的分析,我们先定义出来一个水果
和一个蔬菜
的接口方便使用。
水果接口
interface Fruits{
/**
* 名称
*/
name: string
/**
* 生吃
*/
eatRawFood(): void
}
蔬菜接口
interface Vegetables{
/**
* 名称
*/
name: string
/**
* 做菜
*/
cooking() : void
}
1、联合类型
比如一个🍅,我既可以当水果
来吃
,又可以当做蔬菜
来烹饪
。这种场景下,就不能单独定义一个确定类型了。于是就可以用联合类型(A | B)
定义:
function eatTomatoType(type: Fruits | Vegetables) {
//方法体
}
是不是很完美了,你觉得没有问题?
那么问题又来了~ 😄,发现我开始三理三气的了。
比如我现在有一个🍅,我思考打算怎么吃?
function eatTomatoType(type: Fruits | Vegetables) {
console.log(type.name);
type.cooking() //error
type.eatRawFood() //error
}
假设,我现在还没有想好怎么吃?这个🍅的属性还没有定,我发现根本定不下来用什么方法食用~回到程序,就是发现type.cooking()
和type.eatRawFood()
两个方法都不能正常调用。因为既可以是水果
、又可以是蔬菜
,让程序陷入了两难。
这个时候,就是该类型保护
登场。类型保护
最主要的作用就是帮我们确定出来一个合适的操作方式。类型保护是一种处理思维~
仔细看一下代码的代码
function eatTomatoType(type: Fruits | Vegetables) {
console.log(type.name);
//类型“Fruits | Vegetables”上不存在属性“cooking”。类型“Fruits”上不存在属性“cooking”。
// type.cooking()
if('eatRawFood' in type){
//如果type中存在eatRowFood方法,则表示是水果
(type as Fruits).eatRawFood()
} else {
(type as Vegetables).cooking
}
}
这里使用了一个判断,'eatRawFood' in type
是判断,当前type
里面是否包含了eatRawFood
方法。如果当前选择的方式是直接生吃,也就是我们之前定义好的水果类型咯。
class Tomato implements Fruits{
name: string = '🍅';
eatRawFood(): void {
console.log(`${this.name} 是可以直接生吃的~`);
}
}
eatTomatoType(new Tomato())
最终会打印出来
🍅
🍅 是可以直接生吃的~
2、交叉类型
我们还是用黄瓜举例,普通的黄瓜直接吃,口感可能就很一般,现在农科院为了让黄瓜能兼具生吃好吃和烹饪好吃的条件,研究了新品种,水果黄瓜
登场了~
这个时候的水果黄瓜,如果类型表示的话,伪代码可能就是 黄瓜 & 水果
了。
class SuperMarket implements Fruits, Vegetables{
name: string = '🥒放进去了商超里面了';
cooking(): void {
console.log(`${this.name}, 可以买来烹饪!`);
}
eatRawFood(): void {
console.log(`${this.name}, 可以买来生吃!`);
}
}
let shoppingCart: Fruits & Vegetables = new SuperMarket();
shoppingCart.cooking()
shoppingCart.eatRawFood()
好了,现在新研制的水果黄瓜上市了,商超的蔬菜和水果柜台都上架了。当你买回去之后,既可以烹饪,又可以直接生吃。
当然这个例子有点牵强,理解问题就ok了。
3、 类型保护
其实类型保护
在上面已经用过了,下面介绍一下常用的类型保护
方式。
in 类型保护
in
用来判断是否归属于某个类中,上面有用到
'cooking' in Vegetables
typeof类型保护
typeof
是用来比较类型归属
cooking typeof Function
instanceof类型保护
instanceof
主要是用来比较对象
a instanceof A //判断对象归属
自定义类型保护
自定义类型保护,其实就是你自己定义的一个条件。
//比如你的条件如下
A && B //只有在满足了以下条件的时候,才是某个安全的类型
感觉各位大佬看到这里,此致~敬礼