欢迎光临散文网 会员登陆 & 注册

TypeScript 类型基础——类型收窄

2023-07-21 16:29 作者:没用软件开发日记  | 我要投稿

    类型收窄的目的等同于接口隔离原则ISP的目的,只把消费者需要的提供给消费者。

    这是一个类型收窄最简单的例子,因为getName函数内部只用到了info类进对象中的name字段,所以在参数位置使用解包的形式,将参数对象中的name字段提取出来。这样做屏蔽了其他不需要了解的细节,让函数真正的专注于某一功能。

    之前讲过的将子类型对象传给需要其基类的函数和此例是没有关联的,因为被传入的对象没有真的因为函数的参数类型被标记为其基类,就真的只将自己基类部分字段传入。这只是TS的编译期魔法,在运行时因为浏览器无法解析TS语言,所以实际上浏览器执行的是TS编译后的JS结果,也就是说传入函数的依然是整个子类型对象。

    这个示例是一个联合类型拆解的最简单方案,利用typeof操作符判定对象类型执行不同的操作,在每个if分支体现的同样是类型收窄的思想。

    当然了typeof无法很好的判断复杂类型,比如Date或者我们自定义的class,这个时候我们可以使用“instanceof”操作符来判断类型,已达到类型收窄的目的。

    这是TS官方文档上的一个高端的例子,在这个例子中使用“in”操作符判断字段是否存在于对象中,TS很聪明的发现Bird类型中不存在swim字段,所以如果animal参数内包含swim那么它一定是Fish。

    在官方文档上有这样一个例子,当我们过滤一个联合类型的数组时,我们通常过滤的结果类型一致,这时候我们可以使用“类型谓词”来标定类型。通过pet is Fish,我们可以提示TS:该函数的参数虽然是联合类型但是事实上被传入的对象都符合Fish类型描述,再配合函数内部的对Fish的精准判断,那么zoo函数被filter后就只会返回只含有Fish类型的数组了,此时underWater1的类型也会被标记为Fish[ ]。

    在使用策略模式时,我们需要的更多的是确定的值而不是string这种泛泛的类型,在上面的例子中我们使用“as const”来将原本的string[ ]类型转换成类型readonly ["1", "2", "3"]类型,也就是说即使我们为arr重新赋值也只能是["1", "2", "3"],这样在下面的forof循环中iterator的类型就是“1”、“2”、“3”中的其中一个了。

    在官方文档中有这样一个例子,在这个例子中使用never标记不可能存在的值,在策略模式中非常好用,我们可以在异常分支返回never,如果一个非never值赋给了never对象则会产生异常。


TypeScript 类型基础——类型收窄的评论 (共 条)

分享到微博请遵守国家法律