TypeScript如何定义符合联合类型全键要求的无索引报错泛型对象类型
解决方案
你遇到的报错是因为泛型参数没有加合法索引类型约束,TS 无法确认传入的泛型 T 可以作为对象的键使用,正确定义如下:
// 方法1:手写映射类型 type Keys<T extends PropertyKey> = { [K in T]: number } // 方法2:用TS内置工具类型简化写法,和上述实现效果完全等价 type Keys<T extends PropertyKey> = Record<T, number>
效果验证
// 合法用法:包含所有要求的键,无额外键,值均为number类型 const obj: Keys<"x" | "y"> = { "x": 1, "y": 2 }; obj["x"] // 类型正常,返回number,无报错 obj.x // 点语法访问也符合预期 // 错误情况1:缺少要求的键 const obj1: Keys<"x" | "y"> = { "x": 1 } // TS报错:类型 "{ x: number; }" 中缺少属性 "y" // 错误情况2:存在超出范围的额外键 const obj2: Keys<"x" | "y"> = { "x": 1, "y": 2, "z": 3 } // TS报错:对象字面量只能指定已知属性,并且"z"不在类型"Keys<"x" | "y">"中
特殊场景补充
如果索引访问时依然出现类型报错,检查你用来索引的变量类型:如果索引值是string类型的通用变量而非固定字面量类型,需要将其类型收窄到属于泛型T的成员:
const key = "x" as string obj[key] // 会报错,因为TS无法确认通用string属于T的范围 // 改为如下写法即可正常访问 const key = "x" as const obj[key]
内容的提问来源于stack exchange,提问作者user6118986
相关产品推荐
相关产品推荐

