为何泛型类型与具体类型的条件类型求值结果不同?
TypeScript条件类型中never的处理差异解析
先看你提到的几个类型定义和结果:
首先是泛型版本的ToArray:
type ToArray<Type> = Type extends any ? Type[] : never;
当调用ToArray<string & number>时,结果是never;但直接写条件类型:
type Thing = (string & number) extends any ? never[] : never; // 类型为never[]
再看你补充的示例:
type Thing = string & number; // 类型为never type OtherThing = Thing extends any ? Thing[] : never; // 类型为never[] type OtherOtherThing = ToArray<Thing>; // 类型为never
核心原因:分布式条件类型的特性
这里的关键差异在于是否触发了分布式条件类型:
泛型条件类型会触发分布式逻辑
ToArray<Type>是泛型条件类型,当条件类型的左侧是泛型参数时,TypeScript会自动开启「分布式」行为:如果泛型参数是联合类型,会拆分成每个成员单独进行条件判断,最后把结果合并成新的联合类型。
而never本质是「空的类型集合」,当把never作为泛型参数传入分布式条件类型时,因为没有任何可分发的成员,整个表达式直接返回never,所以ToArray<never>的结果是never。非泛型的条件类型不会触发分布式
像Thing extends any ? Thing[] : never这种直接写的条件类型,没有用到泛型参数,所以不会触发分布式逻辑。此时TypeScript会直接判断never extends any——因为never是所有类型的子类型,这个判断结果为真,所以会返回never[]。
总结一下:
- 泛型条件类型处理
never时,分布式逻辑会直接返回never - 普通条件类型处理
never时,会正常执行分支判断,返回对应结果
内容的提问来源于stack exchange,提问作者D.J. Price
相关产品推荐
相关产品推荐

