TypeScript中`never extends never`的异常行为及原因咨询
问题解析:never在条件类型中的特殊行为
核心原因:分布式条件类型的特性
TypeScript的条件类型有个特殊规则:当条件判断的左侧是裸类型参数(没有被数组、对象等包裹的类型参数)时,会触发分布式条件类型——如果传入的是联合类型,会把每个成员单独代入判断,最终返回各分支的联合结果。
而never是个特殊的空类型,相当于没有成员的联合类型。当裸类型参数传入never时,分布式展开没有任何分支可执行,整个条件类型直接返回never,不会进行never extends never的常规判断。
先看你的测试用例t4
type test<T, F> = T extends F ? 1 : 2 type t4 = test<never, never> // 结果是never,而非预期的1
这里T是裸类型参数,传入never后触发分布式条件类型。因为never没有成员,分布式展开后没有分支运行,所以test直接返回never。
而t3里的never extends never ? 1 : 2不是裸类型参数的判断,不会触发分布式,所以能正常判断never可以赋值给never,返回1。
回到你的FilterOut实现问题
t1的执行逻辑
处理FilterOut<[never], never>时:
- 元组
[never]被推断为X = never,Y = [] - 执行
X extends F(即never extends never),因为X是裸类型参数,触发分布式条件类型,直接返回never - 此时整个三元表达式的结果是
never,不会走后续的递归分支,最终FilterOut返回never
t2的执行逻辑
处理FilterOut<[never, 'a'], never>时:
- 元组被推断为
X = never,Y = ['a'] - 同样
X extends F触发分布式条件类型,返回never - 三元表达式结果为
never,后续递归不会执行,最终返回never
为什么[X] extends [F]能修复问题
把X和F包裹进元组后,条件判断的左侧不再是裸类型参数,而是一个元组类型,不会触发分布式条件类型。此时[never] extends [never]会正常判断为true,从而正确执行过滤逻辑:
- 遇到
never元素时,跳过添加到结果数组,继续递归处理剩余元组 - 遇到非
never元素时,添加到结果数组,最终得到预期的空数组或['a']
内容的提问来源于stack exchange,提问作者Jiangqi Zhu
相关产品推荐
相关产品推荐

