typescript中类型保护有什么用?怎样实现类型保护?
Admin 2021-08-26 群英技术资讯 673 次浏览
这篇文章主要介绍typescript中的类型保护,很多新手可能对类型保护不是很了解,下文有具体的介绍和实例,感兴趣的朋友可以参考下,希望大家阅读完这篇文章能有所收获,接下来小编带着大家一起了解看看。
在 TypeScript 中使用联合类型时,往往会碰到这种尴尬的情况:
interface Bird { // 独有方法 fly(); // 共有方法 layEggs(); } interface Fish { // 独有方法 swim(); // 共有方法 layEggs(); } function getSmallPet(): Fish | Bird { // ... } let pet = getSmallPet(); pet.layEggs(); // 正常 pet.swim(); // ts 报错
如上所示,getSmallPet函数中,既可以返回 Fish 类型的对象,又可以返回 Bird 类型的对象。由于返回的对象类型不确定,所以使用联合类型对象共有的方法时,一切正常,但是使用联合类型对象各自独有的方法时,ts 会报错。
那么如何解决这个问题呢?最粗暴的方法当然是将联合类型转换为 any,不过这种方法不值得提倡,毕竟我们写的是 TypeScript 而不是 AnyScript。
此时,我们使用今天的主角――类型保护,闪亮登场,它可以完美的解决这个问题。孔乙己说过,茴香豆有四种写法,同理,实现类型保护,也有四种写法。
类型断言是最常用的一种类型保护方法,即直接指定类型。由于,TypeScript 中识别的类型大多是靠 TypeScript 的自动类型推算算出来的,所以会出现上面所说的那种问题,即 TypeScript 不知道具体对象类型是什么,所以不确定有没有联合类型各自独有的方法。
当使用类型断言直接指定类型时,相当于你让 TypeScript 开启了上帝模式,可以直接知道具体类型是联合类型中的那个,此时再使用对象的独有方法就符合 TypeScript 的推断了。
interface Bird { // 独有方法 fly(); // 共有方法 layEggs(); } interface Fish { // 独有方法 swim(); // 共有方法 layEggs(); } function getSmallPet(): Fish | Bird { // ... } let pet = getSmallPet(); pet.layEggs(); // 正常 // 通过鸭子类型来进行判断 if ((pet as Bird).fly) { // 类型断言 (pet as Bird).fly() } else { // 类型断言 (pet as Fish).swim() }
如果嫌弃通过 as 来进行类型断言不够上流,还可以使用类泛型的写法,即:
let pet = getSmallPet(); pet.layEggs(); // 正常 // 通过鸭子类型来进行判断 if ((<Bird>pet).fly) { (<Bird>pet).fly() } else { (<Fish>pet).swim() }
tips:友情提示,虽然使用类泛型写法进行类型断言看起来高端一些,但是由于在 tsx 中语法存在歧义,所以为了统一起见,推荐使用 as 的方法进行类型断言。
在js中,我们经常使用 in 语法来判断指定的属性是否在指定的对象或其原型链中。同理,在 TypeScript 中,我们可以通过这种方法确认对象类型。
interface Bird { // 独有方法 fly(); // 共有方法 layEggs(); } interface Fish { // 独有方法 swim(); // 共有方法 layEggs(); } function getSmallPet(): Fish | Bird { // ... } let pet = getSmallPet(); pet.layEggs(); // 正常 // 使用 in 语法进行类型保护 if ('fly' in pet) { pet.fly() } else { pet.swim() }
原理同类型断言一样,都是引导 TypeScript 的类型推断,确定对象类型。
当联合类型中使用的是 class 而不是 interface 时,instanceof 语法就派上用场了,通过 instanceof 语法可以区分不同的 class 类型。
class Bird { // 独有方法 fly() {}; // 共有方法 layEggs() {}; } class Fish { // 独有方法 swim() {}; // 共有方法 layEggs() {}; } function getSmallPet(): Fish | Bird { // ... } let pet = getSmallPet(); pet.layEggs(); // 正常 // 使用 in 语法进行 if (pet instanceof Bird) { pet.fly() } else { pet.swim() }
typeof 语法不同于 in 语法以及 instanceof 语法,in 语法以及 instanceof 语法都是用来引导类型推断进行不同对象类型推断,而 typeof 语法常用于基本类型的推断(或者是联合使用基本类型和对象类型)。
简而言之,当使用 typeof 能够区分联合类型中的不同类型时,即可使用它。
function getSmallPet(): number | string { // ... } let pet = getSmallPet(); if (typeof pet === 'number') { pet++ } else { pet = Number(pet) + 1 }
就如茴香豆的四种写法的本质依然是茴香豆一样,类型保护的四种写法的本质也是一样的,即,引导 TypeScript 中的类型推断将类型推断的多选题变为单选题,这就是类型保护的本质。
以上就是typescript类型保护的相关介绍,希望本文对大家学习和理解类型保护有帮助,想要了解更多typescript类型保护的内容,大家可以关注其他相关文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
vue实现动态样式的方法有哪些?vue中我们想要实现动态样式的方法有很多,因此本文给大家分享几个vue实现动态样式实例供大家参考,对新手学习和理解vue实现动态样式有一定的帮助,接下来跟随小编来学习一下吧。
这篇文章主要为大家介绍了原生javascript中检查对象是否为空示例实现,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
定义新的构造函数,并在内部使用call()调用希望继承的结构函数,绑定this。借助中间函数F实现原型链继承,最好通过封装的inherits函数完成。在新的构造函数原型上继续定义新的方法。
本文实例为大家分享了小程序实现侧滑删除的具体代码,供大家参考,具体内容如下1.页面布局view class=dialogue-box scroll-view scroll-y=true style=height:{{winHeight-50}}px view class=top-list
随着 Vite2 的发布并日趋稳定,现在越来越多的项目开始尝试使用它。本文我们就介绍了Vite创建项目的实现步骤,感兴趣的可以了解一下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008