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

为何TypeScript的Extract工具类型提取子集而非返回完整联合类型?

TypeScript Extract工具类型与直接条件类型的差异解析

先看你给出的代码示例:

Extract工具类型的使用:

type x = 'abc' | 'def' | 32;
type x2 = Extract<x, number>;
// ^? type x2: 32

Extract的官方定义是:

type Extract<T, U> = T extends U ? T : never;

但你直接写下面的代码时,结果却是never:

type x2 = x extends number ? x : never;
// ^? type x2: never

核心原因:分布式条件类型的触发规则

TypeScript里的条件类型有个特殊行为:当条件类型的左侧操作数是联合类型,且这个联合类型处于泛型参数的位置时,会触发分布式条件类型——也就是把联合类型的每个成员单独拆分出来,分别执行条件判断,最后将所有结果合并成新的联合类型。

Extract之所以能得到正确结果,就是因为它是泛型定义:

  • 把联合类型x拆分成'abc'、'def'、32三个成员
  • 依次判断每个成员是否extends number:
    • 'abc' extends number → 不成立,返回never
    • 'def' extends number → 不成立,返回never
    • 32 extends number → 成立,返回32
  • 最终合并结果为never | never | 32,也就是32

而你直接写x extends number ? x : never时,x是作为一个整体的联合类型来判断的——整个'abc' | 'def' | 32是否能赋值给number?显然不行,因为里面包含字符串类型,所以条件不成立,直接返回never。

如果要模拟Extract的效果,只要把逻辑封装成泛型类型,让联合类型处于泛型参数位置即可:

type MyExtract<T, U> = T extends U ? T : never;
type x2 = MyExtract<x, number>; // 结果同样是32

内容的提问来源于stack exchange,提问作者coure2011

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:35:51