Angular中如何通过动态字符串变量获取TypeMap中定义的对应类型?
嗨,我完全懂你遇到的困扰——用静态写死的"Bus"字符串能正常索引TypeMap拿到对应类型,但换成函数返回的动态字符串就报错,说TypeMap没有string类型的索引签名。这其实是TypeScript的类型推断规则在起作用,我来给你一步步梳理解决办法:
问题根源
你的getSelectedEquipmentType()函数,TypeScript默认会把它的返回值推断成宽泛的string类型,而不是你实际返回的"Bus"这个具体的字面量类型。但TypeMap的键是"Bus"、"Area"这类明确的字面量,宽泛的string类型没法匹配这些精准的键,所以才会抛出错误。
解决方案
我们只需要让TypeScript明确知道,getSelectedEquipmentType()返回的是TypeMap的合法键类型就行,有两种实用的实现方式:
方式一:给函数指定返回类型为keyof TypeMap
直接把函数的返回类型约束成TypeMap所有键的联合类型,这样TypeScript就清楚返回值只会是"Bus"、"Area"这类合法值:
interface Bus { id: number; test?: string; } interface Area{ id: number; load?: string; } type TypeMap= { Bus: Bus, Area: Area, // 可以继续扩展其他类型 } func1(){ const equipmentType1 = "Bus" const equipmentType2 = this.getSelectedEquipmentType() type myType1 = TypeMap[typeof equipmentType1]; // 正常推断为Bus类型 type myType2 = TypeMap[typeof equipmentType2]; // 现在能正确推断对应类型了! let myObj1: myType1 = {id:1}; let myObj2: myType1 = {id:1,test:"1"}; // 注意:下面这行代码会报错,因为Bus类型要求必须有id属性 // let myObj3: myType1 = {test:"1"}; } getSelectedEquipmentType(): keyof TypeMap { return "Bus" }
方式二:用as const断言锁定返回值的字面量类型
如果你的函数返回的是固定不变的字面量,也可以用as const让TypeScript把返回值推断成具体的字面量,而不是宽泛的string:
getSelectedEquipmentType() { return "Bus" as const }
这种方式适合返回值固定的场景,要是以后函数可能返回"Bus"或"Area"这类多种值,还是第一种方式更灵活。
额外小提示
如果getSelectedEquipmentType()可能返回多种合法类型(比如有时返回"Bus",有时返回"Area"),那myType2会自动推断成Bus | Area的联合类型,你依然可以正常创建对应类型的变量,TypeScript会帮你做好类型检查。
备注:内容来源于stack exchange,提问作者once in an blue moon

