You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript条件类型为何匹配string/number正常却对boolean返回never?

TypeScript条件类型为何匹配string/number正常却对boolean返回never?

这个问题确实有点绕,我来给你拆解一下背后的原因。

核心问题出在TypeScript的分布式条件类型机制上,你的OutputFor<T>定义刚好触发了这个机制,导致boolean的处理逻辑跑偏了。

先理清楚关键的几个点:

  • 你的InputTypes是string | boolean | number,属于联合类型。
  • OutputFor<T>里的条件检查T extends InputTypes[]中,T是一个「裸类型参数」——也就是没有被元组、对象等包裹的类型参数,这会触发TypeScript的分布式条件类型规则。

按照TypeScript的规则,当条件类型的左侧是裸类型参数,右侧是联合类型时,会自动把条件类型拆分成联合类型每个成员的单独检查,最终结果是所有分支的联合。但这里有个容易踩坑的点:TypeScript会把InputTypes[](联合类型的数组)错误地解析成「T是否属于InputTypes的成员」,而不是「T是否是这个联合类型的数组」。

具体到你调用OutputFor<boolean>的场景:

  1. TypeScript会把boolean extends InputTypes[]解析成boolean extends string | boolean | number,这个判断是true(因为boolean是InputTypes的成员),所以会走条件的then分支:OutputFor<T[number]>。
  2. 但T是boolean类型,T[number]也就是boolean[number],这是个never类型——毕竟boolean不是数组,不存在number索引的成员。
  3. 接下来调用OutputFor<never>,此时never extends InputTypes[]是false,走else分支:Extract<TypePairs, {input: never}>["output"],而Extract从TypePairs里找不到匹配{input: never}的成员,所以返回never,最终结果就是never。

那为什么string和number的情况能正常返回呢?
这是因为当调用OutputFor<string>时,虽然同样会触发分布式条件类型,走then分支OutputFor<string[number]>,但string[number]的结果还是string,递归调用OutputFor<string>时,TypeScript能识别出这种递归并终止,最终返回正确的string类型。number的情况也是同理。

要解决这个问题,你只需要阻止分布式条件类型的触发就行——把T包裹在元组里,让它不再是裸类型参数:

type OutputFor<T> = [T] extends InputTypes[] ? OutputFor<T[number]> : Extract<TypePairs, { input: T }>["output"];

这样TypeScript就会正确解析条件检查,boolean不属于数组类型,会走else分支,Extract就能正常返回boolean类型了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 13:04:32