17. TypeScript 联合类型和类型保护

目录
文章目录隐藏
  1. 联合类型展示
  2. 类型保护-类型断言
  3. 类型保护-in 语法
  4. 类型保护-typeof 语法
  5. 类型保护-instanceof 语法
  6. 总结

这节我将带大家学习一下 TypeScript 联合类型和相关的类型保护知识,需要注意的是,只有联合类型存在的情况下,才需要类型保护。普通的类型注解,并不需要我们这种特殊操作。那先来看一下什么是联合类型。

联合类型展示

所谓联合类型,可以认为一个变量可能有两种或两种以上的类型。用代码举个例子,声明两个接口Waiter(服务员)接口和Teacher(技师)接口,然后在写一个judgeWho(判断是谁)的方法,里边传入一个animal(任意值),这时候可以是Waiter,也可能是Teacher。所以我们使用了联合类型,关键符号是|(竖线)。

interface Waiter {
  anjiao: boolean;
  say: () => {};
}

interface Teacher {
  anjiao: boolean;
  skill: () => {};
}

function judgeWho(animal: Waiter | Teacher) {}

通过这个简单的例子,你应该知道什么是联合类型了。

function judgeWho(animal: Waiter | Teacher) {
  animal.say();
}

但这时候问题来了,如果我直接写一个这样的方法,就会报错,因为judgeWho不能准确的判断联合类型具体的实例是什么。

这时候就需要再引出一个概念叫做类型保护,类型保护有很多种方法,这节讲几个最常使用的。

类型保护-类型断言

类型断言就是通过断言的方式确定传递过来的准确值,比如上面的程序,如果会anjiao(按脚),说明他就是技师,这时候就可以通过断言animal as Teacher,然后直接调用skill方法,程序就不再报错了。同样如果不会按脚,说明就是不同的服务员,这时候调用say()方法,就不会报错了。这就是通过断言的方式进行类型保护。也是最常见的一种类型保护形式。具体看代码:

interface Waiter {
  anjiao: boolean;
  say: () => {};
}

interface Teacher {
  anjiao: boolean;
  skill: () => {};
}

function judgeWho(animal: Waiter | Teacher) {
  if (animal.anjiao) {
    (animal as Teacher).skill();
  }else{
    (animal as Waiter).say();
  }
}

类型保护-in 语法

我们还经常使用in语法来作类型保护,比如用if来判断animal里有没有skill()方法。

这里你可以赋值上面的judgeWho()方法,然后改一下名字,我这里改成了judgeWhoTwo()方法,具体程序如下:

function judgeWhoTwo(animal: Waiter | Teacher) {
  if ("skill" in animal) {
    animal.skill();
  } else {
    animal.say();
  }
}

这里的else部分能够自动判断,得益于TypeScript的自动判断。

类型保护-typeof 语法

先来写一个新的add方法,方法接收两个参数,这两个参数可以是数字number也可以是字符串string,如果我们不做任何的类型保护,只是相加,这时候就会报错。代码如下:

function add(first: string | number, second: string | number) {
  return first + second;
}

解决这个问题,就可以直接使用typeof来进行解决。

function add(first: string | number, second: string | number) {
  if (typeof first === "string" || typeof second === "string") {
    return `${first}${second}`;
  }
  return first + second;
}

像上面这样写,就不报错了。这样就可以继续开心的编写程序了。

类型保护-instanceof 语法

比如现在要作类型保护的是一个对象,这时候就可以使用instanceof语法来作。现在先写一个NumberObj的类,代码如下:

class NumberObj {
  count: number;
}

然后我们再写一个addObj的方法,这时候传递过来的参数,可以是任意的object,也可以是NumberObj的实例,然后我们返回相加值,当然不进行类型保护,这段代码一定是错误的。

function addObj(first: object | NumberObj, second: object | NumberObj) {
  return first.count + second.count;
}

报错不要紧,直接使用instanceof语法进行判断一下,就可以解决问题。

function addObj(first: object | NumberObj, second: object | NumberObj) {
  if (first instanceof NumberObj && second instanceof NumberObj) {
    return first.count + second.count;
  }
  return 0;
}

另外要说的是,instanceof 只能用在类上。

总结

本文我们主要介绍四种类型保护的方式,每种方式都在不同场景中使用(还有一些不太常用的类型保护方式,我就不讲了),你需要自己深刻理解,多练习,在开发时才能灵活使用。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 17. TypeScript 联合类型和类型保护

发表回复