TypeScript中对象属性模板字面量类型回退为原始类型报错如何解决
问题成因
- 你定义的
Obj类型要求对象必须同时包含charge_1_a、charge_1_b、charge_2_a、charge_2_b四个属性,但代码中构造的obj仅根据传入的id生成了两个属性,天然缺少另外一组id对应的属性,本身就不满足Obj的类型约束。 - TypeScript对包含联合类型变量的模板字符串作为对象键的推断存在限制:不会将生成的键推断为对应的模板字面量联合类型,而是直接放宽为
string类型的索引签名,所以构造的对象会被推断为{ [x: string]: string }类型,无法匹配Obj的精确键要求,最终触发报错。
解决方案
根据实际需求选择对应方案即可:
场景1:要求返回的对象包含所有id对应的4个属性
直接补全Obj要求的所有必填属性:
type Id = 1 | 2; type Obj = { [key in `charge_${Id}_a` | `charge_${Id}_b`]: string }; function func(id: Id) { const obj: Obj = { charge_1_a: id === 1 ? "a" : "默认值", charge_1_b: id === 1 ? "b" : "默认值", charge_2_a: id === 2 ? "a" : "默认值", charge_2_b: id === 2 ? "b" : "默认值", } return obj; }
场景2:仅需要返回当前传入id对应的2个属性
原有Obj类型定义不符合需求,需要改为泛型动态生成对应id的键,同时通过类型断言规避TypeScript的推断限制:
type Id = 1 | 2; // 泛型T接收具体的id值,仅生成当前id对应的两个键 type Obj<T extends Id> = { [key in `charge_${T}_a` | `charge_${T}_b`]: string }; function func<T extends Id>(id: T): Obj<T> { // 类型断言告知TypeScript返回的对象结构完全符合Obj<T>的约束 return { [`charge_${id}_a`]: "a", [`charge_${id}_b`]: "b", } as Obj<T>; }
内容的提问来源于stack exchange,提问作者Eliya Cohen
相关产品推荐
相关产品推荐

