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
相关产品推荐
相关产品推荐

