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

TypeScript中Extract<>未按预期工作?是我还是类型检查器出错?

问题确认:TypeScript类型检查器限制还是代码问题?

场景与代码实现

我想要构建一个Num类,要求传入的数字字符串名称和数字值必须匹配,不匹配时触发类型错误,示例如下:

const test1 = new Num("two", 2) // 正常通过
const test2 = new Num("two", 3) // 预期触发类型错误

为此我编写了以下类型定义和类:

type Numbers = {
    name: "two",
    type: 2
} | {
    name: "three",
    type: 3
}

class Num<T extends Numbers["type"]> {
    value: T
    typeName: Extract<Numbers, { type: T }>["name"]

    constructor(typeName: Extract<Numbers, { type: T }>["name"], value: T) {
        this.value = value;
        this.typeName = typeName; // 此处出现类型错误
    }
}

出现的类型错误

Type 'Extract<{ name: "two"; type: 2; }, { type: T; }>["name"] | Extract<{ name: "three"; type: 3; }, { type: T; }>["name"]' is not assignable to type 'Extract<{ name: "two"; type: 2; }, { type: T; }>["name"] & Extract<{ name: "three"; type: 3; }, { type: T; }>["name"]'.
  Type 'Extract<{ name: "two"; type: 2; }, { type: T; }>["name"]' is not assignable to type 'Extract<{ name: "two"; type: 2; }, { type: T; }>["name"] & Extract<{ name: "three"; type: 3; }, { type: T; }>["name"]'.
    Type 'string' is not assignable to type 'Extract<{ name: "two"; type: 2; }, { type: T; }>["name"] & Extract<{ name: "three"; type: 3; }, { type: T; }>["name"]'.
      Type 'string' is not assignable to type 'Extract<{ name: "three"; type: 3; }, { type: T; }>["name"]'.
        Type '"two"' is not assignable to type '"three"'.
          Type 'Extract<{ name: "two"; type: 2; }, { type: T; }>["name"]' is not assignable to type 'Extract<{ name: "three"; type: 3; }, { type: T; }>["name"]'.
            Type 'Extract<{ name: "two"; type: 2; }, { type: T; }>' is not assignable to type 'Extract<{ name: "three"; type: 3; }, { type: T; }>'.
              Type '{ type: T; } & { name: "two"; type: 2; }' is not assignable to type 'Extract<{ name: "three"; type: 3; }, { type: T; }>'.

核心疑问

从逻辑上看,构造函数参数typeName和实例属性this.typeName的类型完全一致,赋值操作应该合法,但TypeScript却抛出了类型错误。我想确认:这是TypeScript类型检查器的问题,还是我的代码存在逻辑漏洞?(注:已有替代实现方案,无需提供解决方案)


结论

这是TypeScript类型检查器在处理泛型条件类型时的局限性,并非你的代码逻辑问题。

原因说明

当类的泛型参数T被用于条件类型Extract<Numbers, { type: T }>["name"]时,TypeScript的类型系统无法在构造函数内部精准追踪T对应的具体联合类型分支。它会将该条件类型解析为所有可能分支的交叉类型(即错误信息中的&操作符结果),因为检查器无法确定T到底对应Numbers中的哪一个成员,从而错误地判定typeName的类型与this.typeName不兼容。

本质上,TypeScript对泛型上下文里的条件类型的流分析能力还不完善,导致这种逻辑上完全合法的赋值被误判为类型不兼容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:18:14