怎么在TypeScript中保护类型
怎么在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 的方法进行类型断言。
in语法
在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 的类型推断,确定对象类型。
instanceof 语法
当联合类型中使用的是 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 语法
typeof 语法不同于 in 语法以及 instanceof 语法,in 语法以及 instanceof 语法都是用来引导类型推断进行不同对象类型推断,而 typeof 语法常用于基本类型的推断(或者是联合使用基本类型和对象类型)。
简而言之,当使用 typeof 能够区分联合类型中的不同类型时,即可使用它。
function getSmallPet(): number | string { // ...}let pet = getSmallPet();if (typeof pet === 'number') { pet++} else { pet = Number(pet) + 1}
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网行业资讯频道,感谢您对编程网的支持。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341