如何在TypeScript中实现基于属性值的动态属性类型解析?
实现TypeScript多态关联的类型动态匹配
要让ExampleSubject的type和subject类型实现动态关联,你需要将ExampleSubject定义为联合类型,让每个联合成员对应一组匹配的type和subject类型,而非单一接口。
基础实现方案
interface SubjectA {} interface SubjectB {} interface SubjectC {} enum SubjectType { SubjectA = 'Subject A', SubjectB = 'Subject B', SubjectC = 'Subject C', } // 定义联合类型,强制type与subject类型一一绑定 type ExampleSubject = | { type: SubjectType.SubjectA; subject: SubjectA } | { type: SubjectType.SubjectB; subject: SubjectB } | { type: SubjectType.SubjectC; subject: SubjectC };
定义完成后,TypeScript会自动做类型校验:
- 当
type指定为SubjectType.SubjectA时,subject必须是SubjectA类型 - 当
type指定为SubjectType.SubjectB时,subject必须是SubjectB类型 - 类型不匹配时会直接抛出编译错误
示例验证:
// 合法:type与subject类型匹配 const validA: ExampleSubject = { type: SubjectType.SubjectA, subject: {} }; // 非法:type为SubjectA但subject是SubjectB类型,TypeScript会报错 const invalid: ExampleSubject = { type: SubjectType.SubjectA, subject: {} as SubjectB };
可扩展实现方案
如果后续需要新增更多Subject类型,手动维护联合成员会很繁琐,你可以用映射类型自动生成关联关系:
interface SubjectA {} interface SubjectB {} interface SubjectC {} enum SubjectType { SubjectA = 'Subject A', SubjectB = 'Subject B', SubjectC = 'Subject C', } // 建立SubjectType到对应接口的映射表 type SubjectMap = { [SubjectType.SubjectA]: SubjectA; [SubjectType.SubjectB]: SubjectB; [SubjectType.SubjectC]: SubjectC; }; // 通过映射类型自动生成ExampleSubject联合类型 type ExampleSubject = { [K in keyof SubjectMap]: { type: K; subject: SubjectMap[K]; }; }[keyof SubjectMap];
这种方式下,新增Subject类型时只需要两步:
- 新增对应的接口(如
SubjectD) - 在
SubjectType枚举和SubjectMap中添加对应项
无需修改ExampleSubject的定义,扩展性更强。
内容的提问来源于stack exchange,提问作者Harish Kumar
相关产品推荐
相关产品推荐

