该系列文章是本人阅读阮一峰老师的《TypeScript教程》学习笔记,欢迎各位大佬指出不正确的地方,感谢!
any类型
any类型表示没有任何限制,该类型的变量可以赋予任意类型的值。
变量类型一旦设为any,TS实际上会关闭这个变量的类型检查,只要语句正确,即使有明显的类型错误也不会报错,所以在TS中应该尽量避免使用any类型。
any类型的使用场景
- 出于特殊原因,需要关闭某些变量的类型检查,就可以把该变量的类型设为any;
- 为了适配以前老的JS项目,让代码快速迁移到TS,可以把变量设为any。
从集合论的角度看,any类型可以看成是其他类型的全集,包含了一切可能的类型。TS将这种类型称为“顶层类型”,意为涵盖了所有下层。
类型推断问题
对于开发者而言没有指定类型、TS必须自己推断的那些变量,如果无法推断出类型,TS就会认为该变量的类型是any类型。
TS提供了一个编译选项noImplicitAny,打开这个选项,只要推断出any类型就会报错。
但如果是使用let或var命令声明变量,不赋值也不指定类型是不会报错的。所以用let或var声明的变量不赋值时,就一定要显式声明类型,否则可能存在安全隐患。
const命令没有这个问题,因为TS要求const声明变量时,必须同时进行初始化(赋值)。
污染问题
any类型除了关闭类型检查,还有一个很大的问题,就是会“污染”其他变量。它可以赋值给其他任何类型的变量(因为没有类型检查),导致其他变量出错。
unknown类型
为了解决any类型“污染”其他变量的问题而诞生的,可是视为严格版的any,一般使用any类型的地方应该要优先考虑设置为unknown类型。
跟any类型的相似之处在于所有类型都能分配给unknown类型,不同之处在于,unknown类型不能直接使用:
- unknown类型的变量,不能直接赋值给其他类型的变量(除了any类型和unknown类型);
- 不能直接调用unknown类型变量的方法和属性;
- unknown类型变量能够进行的运算是有限的,只能进行比较运算、取反运算、typeof运算和instanceof运算符这几种,其他的运算都会报错。
在集合论上,unknown也可以视为其他类型(除any)的全集,所以它和any一样,也属于TS的顶层类型。
never类型
为了保持与集合论的对应关系,以及类型运算的完整性,TS还引入了“空类型”的概念,即该类型为空,不包含任何值。
由于不存在任何属于“空类型”的值,所以该类型被称为never,即不可能有这样的值。
主要的使用场景就是保证类型运算的完整性,以及不可能返回值的函数,返回值类型就可以写成never。
never类型的一个重要特点是,可以赋值给任意其他类型。
因为从集合论来说,空集是任何集合的子集。TS就相应规定,任何类型都包含了never类型。因此,never类型是任何其他类型所共有的,TS把这种情况称为“底层类型”。