一、unknown
类型
unknown
类型是TS3新增的类型,这个类型与 any
类型类似,
可以设置任何的类型值,随后可以更改类型。因此,
我们可以将变量先设置为字符串类型,然后再将其设置为数字类型,
如果事先不检查类型,使用any
类型,调用了不存在的方法,编译时不会报错,代码运行时才会发现错误。
但是使用unknown
类型不一样,如果不进行类型判断,执行相关操作编译器就会报错。文字说了这么多,还是上代码,更容易理解些。
1. 关于any
的问题
首先我们创建一个 any.ts 的文件,代码如下:
1 | let val: any = 22; |
运行编译后的代码,并不会报错,也是按照我们的预期输出: [33]。
由于是any
类型,我们可以随意更改类型,当变成数组类型时,我们调用push
方法进行内容操作,看似没啥问题,如果我们开发人员,如果由于疏忽,打错了一个不存在的方法,ts代码能正常编译吗?
1 | let val: any = 22; |
当运行 tsc any 命令后,你会发现编译器能顺利编译,当我们运行 node any,编译后的代码能正常执行吗?答案是显而易见的,会报异常,你会在控制台发现以下错误:
1 | val.doesnotexist(33); |
上述的错误,大家可能不会犯,但是项目大时,参与的人多时,就很难避免这样类似的问题,因此unknown
类型出现了。
2. 一段 unknown 类型的代码
接下来我们来看看它是怎么解决类似的问题,我们还是从一段简单的代码开始,如下段代码所示:
1 | let val: unknown = 22; |
当你编译此代码时,你会立马收到如下报错:
1 | Property 'push' does not exist on type 'unknown'. |
是不是很奇怪,虽然我们将其类型更改为数组类型,但是编译器不认识,它认为unknown类型,这个类型没有push方法,当然会报错,除非先判断类型,如果是相关类型且正确执行相关方法,编译器则会顺利通过,如下段代码所示:
1 | let val: unknown = 22; |
虽然有些麻烦,但是相比any
类型说,更加安全,在代码编译期间,就能帮我们发现由于类型造成的问题,因此在大多的场景,建议使用unknown
类型替代any
。
二、never
类型
这个类型看起来有些奇怪,乍一看,看起来和void相似,但是其完全不一样。
从字面意思上来说,表示一个从来不会有返回值的函数(例:while(true) {}
),
一个总是会抛出错误的函数(function foo() { throw new Error('Not Implemented') }
)。
那么问题来了,它和void
类型啥区别,void
表示没有任何类型,函数没有返回值时(可以返回,但是没值),
我们可以设置为void
类型;never
这不一样,一个函数根本就没返回(或者总是出错,永远不会有返回值)。
看文字有些费劲,我们还是来看一段简单的代码来理解下吧,如下所示:
1 | function alwaysThrows(): never { |
当我们编译上述代码时,编译器就会报错,如下所示:
1 | Type 'number' is not assignable to type 'never'. |
编译器已经很明确地告诉了我们never
类型不应该返回任何值(或抛异常)。那么问题来了,这个类型有啥用呢?我们还是举个例子来理解下吧,比如你有个enum
枚举类型,代码如下所示:
1 | enum TestNeverEnum { |
在switch
当中判断type
,TS是可以收窄类型的 (discriminated union
):
1 | enum TestNeverEnum { |
注意在default
里面我们把被收窄为never
的returnValue赋值给一个显式声明为never
的变量。如果一切逻辑正确,
那么这里应该能够编译通过。但是假如有一天你的同事增加了TestNeverEnum
枚举类型:
1 | enum TestNeverEnum { |
然而他忘记了在getEnumValue
里面加上针对THIRD
的处理逻辑,
这个时候在default branch里面returnValue会被收窄为TestNeverEnum.THIRD
,导致无法赋值给never
(因为有值返回),产生一个编译错误。编译器会产生如下的错误:
1 | Type 'TestNeverEnum' is not assignable to type 'never'. |
所以通过这个办法,你可以确保getEnumValue
方法里总是穷尽 (TestNeverEnum) 了所有All的可能类型,目的就是写出类型绝对安全的代码。
- 本文标题:细品TypeScript中unknown和never类型
- 本文作者:Jacshuo
- 创建时间:2022-06-07 23:18:45
- 本文链接:https://blog.imade.life/2022/06/07/细品TypeScript中unknown和never类型/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!