如何根据模板字面量类型的键设置TypeScript对象值类型
问题:TypeScript中如何让模板字面量键前缀对应正确的对象类型
我正在学习TypeScript,希望理解如何根据模板字面量类型的键来设置对象类型。以下是示例代码:
interface Circle { radius: number; } interface Square { length: number; } type TypeName = "circle" | "square"; type ObjectType<T> = T extends "circle" ? Circle : T extends "square" ? Square : never type Shape = { [id: `${TypeName}.${string}`]: ObjectType<TypeName> } const circle:Shape = {"circle.anythig": {length: 33}} // 这里居然允许赋值Square类型? // ^^^^^^ 怎么强制键名前缀对应正确的对象类型? const square:Shape = {"square.anythig": {length: 33}} // 这个是正确的Square类型
当前问题是:定义的Shape类型中,键前缀为circle的属性却可以赋值Square类型,如何强制键名前缀对应正确的对象类型?
解决方案
要实现键前缀和对应类型的绑定,需要用到带重映射的映射类型结合模板字面量,让每个键的前缀部分动态关联对应的对象类型。具体实现如下:
修正后的类型定义
interface Circle { radius: number; } interface Square { length: number; } type TypeName = "circle" | "square"; type ObjectType<T> = T extends "circle" ? Circle : T extends "square" ? Square : never // 核心:用映射类型遍历TypeName,绑定前缀和对应类型 type Shape = { [K in TypeName as `${K}.${string}`]: ObjectType<K> };
校验效果
现在TypeScript会严格校验键前缀与值类型的对应关系:
// ❌ 错误:类型 "{ length: number; }" 不能赋值给类型 "Circle" const circle: Shape = {"circle.anythig": {length: 33}}; // ✅ 正确:符合Square类型 const square: Shape = {"square.anythig": {length: 33}}; // ✅ 正确:符合Circle类型 const validCircle: Shape = {"circle.test": {radius: 5}};
原理说明
[K in TypeName as${K}.${string}]:这是TypeScript的重映射映射类型,遍历TypeName的每个成员K,将键重写为${K}.${string}格式的模板字面量。ObjectType<K>:这里的K是当前遍历的具体类型("circle"或"square"),因此ObjectType<K>会精准对应Circle或Square,而非之前的联合类型Circle | Square,从而实现了前缀与类型的强绑定。
内容的提问来源于stack exchange,提问作者Alex Yusupov
相关产品推荐
相关产品推荐

