TypeScript 中有几种特殊的类型,分别是 any 、unknown 和 never 。
从集合论的角度理解,unknown 对应于全集,never 对应于空集。
TypeScript 变量之间是否可赋值的规则是:赋值变量的类型包含的值是被赋值变量的类型包含的值的子集。
例如 unknown 对应于全集,不是任何类型的子集,所以 unknown 不能赋值给任何别的类型的变量。never 是空集,任何集合均不是其子集,因此任何别的类型的变量都不能赋值给 never 类型的变量。
但 any 是个例外,any 类型的变量可赋值给任何类型的变量,反之亦成立。如果 any 是一个特定集合的话,这个集合具有这样的性质:任何集合均是其子集且其为任何集合的子集,这显然是矛盾的。
所以我的理解是,any 不是一个特定的集合,而是可变的,它会根据上下文变为任意的集合,以保证无论是赋值还是被赋值时,均满足上边的说的可赋值的规则(亦或者 TypeScript 直接给 any 类型开绿灯,跳过检查?)。
由此我又得出一个推论,在编写一些基础的泛型方法或者工具时,如果可接收任意类型,为了类型安全,应该将泛型限定为 unknown 而不是 any ,例如 UnwrapPromise<T extends Promise<unknown>> = T extends Promise<infer U> ? UnwrapPromise<U> : T
。
不知道这样理解是否是正确的?
1
vilic 2022-07-09 18:58:25 +08:00
感觉理解得没毛病,就是个例外,遇到 any 则终止了双向的类型检查。从类型安全的角度使用 unknown 也是对的。
|
2
Leviathann 2022-07-09 19:00:25 +08:00
any 就是 disable type check
|
3
noe132 2022-07-09 19:03:41 +08:00 via Android
any 具有传染性,所以搞了个 unknown 。很多情况 any 和 unknown 功能完全一致。
|
4
Mexion 2022-07-25 18:13:49 +08:00
any 就是不检测类型,任何类型都可以; unkown 就是安全的 any ,在使用时需要判断类型限定范围才能用
|