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
。
不知道这样理解是否是正确的?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.