TS类型收窄

前言:

本文是对于冴羽大佬的文章 TypeScript 之 Narrowing 的学习笔记。既然是学习笔记,那么将文章照搬过来是没有意义的,本文是笔者对大佬的文章学习之后结合自己的理解做的总结。

类型收窄,让ts能更好的判断某个值的类型,比如一个值可能是number、string、null等类型,通过类型缩窄让ts能准确判断出当前值的类型。

一、类型保护(type guards)

在ts中最常用的收窄就是类型保护,通过判断一个值是否为该类型,让ts能准确知晓该值的类型。可以看到下图,判断arg为string之后,ts能够准确知道arg就是一个string类型并给出string类型的相关提醒。

二、真值缩窄

js中, 0 、NaN、""、null、undefined 这些值都会被转为 false,针对这一特性,可以把这些值给过滤掉

如下图,arg的类型已经从原先的number|null|string 被缩窄为了 string|number

当然使用这一特性时也需要额外关注0、""的情况,如下代码会把arg为0或空字符串的情况过滤掉,因此需要谨慎使用以下方式做真值缩窄

三、等值缩窄

如果一个参数与另一个参数全等,即(a === b),那么ts解析器就会认为a和b不仅值相等,类型也相等。

可以看到下图,原先的x:unknown, 在if分支中,编辑器提示x为string类型

四、in操作符缩窄

js中in可以判断对象是否有某个属性名,通过这个操作符也能让ts进行类型缩窄。

下图通过判断arg有run属性名,让ts将arg的类型缩窄为了Cat

五、instanceof 收窄

很好理解,通过instanceof来收窄类型

六、控制流分析

一个值的可能类型是number和string,那么ts断定如果这个值不是number就一定会是string

在下图中,我们判断arg为number时return,因此在if后面的语句,ts认为arg就是一个string类型

七、类型判断式

使用 is Type的语法来自己定义一个类型保护

如下图isCat函数,通过返回 arg is Cat 来定义一个类型保护,使用isCat之后ts就知道某个值是不是Cat类型

八、可辩别联合

设想一下有一个动物Animal类型,不同的动物都有不同的行为,比如鱼能游泳(swim)但不能飞(fly),猫能跑(run)但不能游泳(swim)。因此这个Animal类型可能会写成这样:

这样做的弊端也很明显,当我们判断类型为bird时,它应该具备能飞(fly)的能力,但是ts会报错,因为fly我们定义的是个可选类型。

要解决这个问题可以使用联合类型

然而使用时仍然会报错,因为ts不知道Animal类型具体是Cat、Fish、还是Bird

这时候依靠type属性名就能让ts正确识别Animal的具体类型,

九、穷尽检查

如果一个值它声明时类型为number|string,如果还有其他情况(如下图),这时候ts就会认为这个值的类型为never。

never表示一个不存在的类型,never可以赋值给任何值,但不能被赋值(同为never类型除外)

使用穷尽检查有什么用呢?设想一下第八章联合类型的例子,如果新增了一个Dog类型,那么在对应的函数里就要加上处理逻辑,这时候要添加处理逻辑的地方过多,有个别地方忘记做处理怎么办?这就可以使用穷尽检查让ts提示一个编译错误

如下图,我们在最后做了兜底,将arg赋值给never类型的finalArg,没有任何错误。

现在新增一个Dog类型, 这个时候ts就会体贴的提示我们这里有编译错误,记得把Dog类型的处理也加上。

相关推荐
「、皓子~13 分钟前
后台管理系统的诞生 - 利用AI 1天完成整个后台管理系统的微服务后端+前端
前端·人工智能·微服务·小程序·go·ai编程·ai写作
就改了16 分钟前
Ajax——在OA系统提升性能的局部刷新
前端·javascript·ajax
凌冰_18 分钟前
Ajax 入门
前端·javascript·ajax
京东零售技术33 分钟前
京东小程序JS API仓颉改造实践
前端
奋飛42 分钟前
TypeScript系列:第六篇 - 编写高质量的TS类型
javascript·typescript·ts·declare·.d.ts
老A技术联盟42 分钟前
从小白入门,基于Cursor开发一个前端小程序之Cursor 编程实践与案例分析
前端·小程序
风铃喵游1 小时前
构建引擎: 打造小程序编译器
前端·小程序·架构
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ThemeClock(主题时钟)
前端·javascript·css·vue.js·前端框架·tailwindcss
小飞悟1 小时前
🎯 什么是模块化?CommonJS 和 ES6 Modules 到底有什么区别?小白也能看懂
前端·javascript·设计
浏览器API调用工程师_Taylor1 小时前
AOP魔法:一招实现登录弹窗的全局拦截与动态处理
前端·javascript·vue.js