本博客 hjy-xh,转载请申明出处
any
在TS中使用any类型,可以用来表示允许赋值给变量任意类型,这种方式与直接使用JS没有太大差别,无法享受到TS的类型检查,在可能出错的地方也不会发现错误。
any类型本质上是类型系统的一个逃逸舱,那我们在什么情况下会使用该类型呢?
- 无法确定当前类型时
- 逐步向TS迁移时
而在编写代码的过程中,明确知道类型的时候,有时为了偷懒,使用了any,这是一种不好的行为。
而以下种种原因,可能都会对我们是否使用any有影响:
- 添加类型时,需要编写大量代码,而
any工作量很少 - 已经通过必要的运行时检查以防御性的方式编写了代码,以确保没有错误
- 有些参数很难正确输入,但是
any更容易 - 不知道参数是什么
- 类型增加了很多复杂性,有时
any更简单
使用any还会造成类型污染的问题:即any类型的对象会导致后续的属性类型都会变成any。
1 | let obj: any = { |
unknown
在TS的3.0版本中,引入了unknown类型,它可以这样理解成:**unknown类型是any的类型安全版本。**
这意味着如果要在TS中使用unknown类型时,需要知道它所指的类型,也就自然地推导出使用该类型的变量前,需要对该变量的类型进行断言。
1 | function func(value: unknown) { |
unknown类型只能被赋值给any类型和unknown类型本身。
因为只有能够保存任意类型值的容器才能保存unknown 类型的值,所以这个限制很合理。毕竟我们不知道变量中存储了什么类型的值。
never
never类型表示的是那些永不存在的值的类型,never类型是任何类型的子类型,也可以赋值给任何类型。
然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外),never用于那些永不可发生的情况:
- 一个从来不会有返回值的函数(如:如果函数内含有
while(true) {}); - 一个总是会抛出错误的函数(如:
function foo() { throw new Error('Not Implemented') },foo 的返回类型是 never);
与 void 的差异
void表示没有任何类型,never表示永远不存在的值的类型
异同
any和unknown是TS中所谓的顶级类型:当把类型看作是值的集合时,any 和 unknown 是包含所有值的集合never类型是TS中的底层类型:空集
以下或许是最佳实践
- 如果不是有意忽略类型检查,不使用
any - 如果要用
any,可以考虑用unknown代替(进行断言后使用)