TypeScript类型挑战:实现IsAny实用类型
99% 的 TypeScript 开发人员都使用过 Any 类型,但只有 20% 的开发人员知道如何检测 Any 类型。为了帮助读者更好地巩固 TypeScript 的知识,我从 Github 上的 type-challenges 库中选择了几十个挑战,与您一起完成类型挑战。
99% 的 TypeScript 开发人员都使用过 Any 类型,但只有 20% 的开发人员知道如何检测 Any 类型。
为了帮助读者更好地巩固 TypeScript 的知识,我从 Github 上的 type-challenges 库中选择了几十个挑战,与您一起完成类型挑战。
挑战
有时候检测是否有 any 类型的值很有用,这在使用第三方 TypeScript 模块时特别有用,因为第三方模块可以在模块 API 中导出 any 类型的值,当你在抑制 implicitAny 检查时,了解 any 也是很有用的。
因此,让我们编写一个实用程序类型 IsAny<T> ,它接受输入类型 T 。如果 T 是 any ,则返回 true ,否则返回 false 。
例如:
type A = IsAny<any> // expected to be true
type B = IsAny<undefined> // expected to be false
type C = IsAny<unknown> // expected to be false
type D = IsAny<never> // expected to be false
type E = IsAny<string> // expected to be false
解决方案
我们的类型挑战是实现 IsAny<T>
泛型,在分析如何实现这个泛型之前,让我们简要介绍 any
类型。
any 类型
在 TypeScript 中, any
类型被称为顶级类型,所谓顶级类型可以理解为泛型父类型,即可以包含所有值的类型。
事实上,any 类型本质上都是类型系统的逃生口,TypeScript允许我们对any 类型的值执行任何操作,而无需执行任何类型的预先检查。
这有什么问题呢?让我们举个例子:
对于上面的 TypeScript 代码,编译时不会提示任何错误,但是在运行时会抛出运行时错误。作为开发者, any
类型给了我们很多自由,但它也带来了一些陷阱。为了解决 any
类型的安全风险,TypeScript 团队在 3.0 中引入了 unknown
类型,你可以理解为类型安全的 any
类型.
我不会深入探讨 any
类型和 unknown
类型之间的区别,但如果您感兴趣,可以阅读下面的文章。
不再对 TypeScript 中的 ‘any’ 和 ‘unknown’ 感到困惑
最后,让我们看一下完整的代码:
type IsAny<T> = 0 extends T & 1 ? true : false
type A = IsAny<any> // true
type B = IsAny<undefined> // false
type C = IsAny<unknown> // false
type D = IsAny<never> // false
type E = IsAny<string> // false
在 TypeScript 中,提供了 &
操作符,用于实现对多个类型的交集操作,得到的新类型称为交集类型。
让我们简单介绍一下 &
操作符,它满足以下规则:
-
同义:
A & A
等价于A
。 -
可交换性:
A & B
等价于B & A
(除了下面提到的调用和构造签名)。 -
结合性:
(A & B) & C
等价于A & (B & C)
。 -
超类型折叠:如果
B
是A
的超类型,则A & B
等价于A
。
在上面的代码中, any
类型和 never
类型是特殊的,除 never
类型外,其他类型与 any
类型相交会导致 any
类型。
在了解了 any
类型的特性之后,让我们来看看当 T
类型参数是不同类型时 T & 1
的输出:
type A1 = any & 1 // any
type B1 = undefined & 1 // never
type C1 = unknown & 1 // 1
type D1 = never & 1 // never
type E1 = string & 1 // never
掌握了以上内容后,剩下的就是 TypeScript 条件类型的相关内容,这里就不介绍了,我推荐你阅读这篇文章(注意:文章链接无法直接点击打开,需要右键复制链接地址到浏览器地址栏中打开):
如果有任何不清楚的地方,请给我留言。
欢迎关注公众号:文本魔术,了解更多
更多推荐
所有评论(0)