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

TypeScript中如何在嵌套对象内实现类型映射的精确匹配?

实现枚举键与关联类型的精确匹配(无需类型断言)

先看你给出的原始代码:

enum MyEnum {
    A,
    B
}

type TypeMap = {
    [MyEnum.A]: string,
    [MyEnum.B]: number
}

interface ObjInterface<T extends keyof TypeMap> {
    obj: T,
    objData: TypeMap[T]
}

interface SecondaryInterface {
    value: string,
    objChosen: ObjInterface<keyof TypeMap>
}

当前问题:创建SecondaryInterface类型的对象时,objData会被推断为string | number的联合类型,哪怕指定了obj: MyEnum.A,编辑器依然提示objData可以是字符串或数字,必须依赖类型断言才能获得精确的类型提示。

问题根源

ObjInterface<keyof TypeMap>会被TypeScript解析为:

{
    obj: MyEnum.A | MyEnum.B,
    objData: string | number
}

这里obj和objData是独立的联合类型,两者没有关联关系,TypeScript无法根据obj的具体值推断objData的精确类型。

解决方案:使用关联联合类型

要让TypeScript识别obj与objData的对应关系,需要将objChosen定义为关联的联合类型,而非泛型接口的单一实例。

方案1:手动构建联合类型

直接把ObjInterface<MyEnum.A> | ObjInterface<MyEnum.B>作为objChosen的类型:

interface SecondaryInterface {
    value: string,
    objChosen: ObjInterface<MyEnum.A> | ObjInterface<MyEnum.B>
}

此时创建对象时,TypeScript会自动根据obj的枚举值推断objData的精确类型:

const myObj: SecondaryInterface = {
    value: "",
    objChosen: { obj: MyEnum.A, objData: "a string" } // objData自动提示string类型
};

const myObj2: SecondaryInterface = {
    value: "",
    objChosen: { obj: MyEnum.B, objData: 123 } // objData自动提示number类型
};

方案2:自动生成关联联合类型(扩展性更好)

如果枚举值较多,手动编写联合类型效率低,可以通过keyof TypeMap自动生成关联联合类型:

// 自动遍历TypeMap的键,生成对应的关联类型联合
type ObjUnion = {
    [T in keyof TypeMap]: ObjInterface<T>
}[keyof TypeMap];

interface SecondaryInterface {
    value: string,
    objChosen: ObjUnion
}

这个写法的核心是:先遍历TypeMap的所有键生成对应ObjInterface<T>类型,再提取所有类型的联合。新增枚举值和TypeMap的对应关系后,ObjUnion会自动更新,无需手动修改。

效果验证

使用上述方案后,无需类型断言,TypeScript会自动完成精确校验:

  • 当obj: MyEnum.A时,objData只能输入字符串,输入数字会直接报错;
  • 当obj: MyEnum.B时,objData只能输入数字,输入字符串会直接报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:30:57