TypeScript中如何使用变量动态访问对象属性?
解决TypeScript中动态访问对象属性的类型报错问题
你遇到的核心问题是TypeScript无法将宽泛的string类型自动缩小为Person接口的具体键类型,导致动态访问属性时触发类型检查错误。咱们来一步步拆解原因和可行的解决方案:
问题根源
你把keys断言成了Array<string>,但Person的键是明确的字面量类型"eyeColor" | "hairLength"。TypeScript的类型检查器无法确认一个string类型的变量一定是Person的合法键,所以会抛出"无法用string类型索引Person"的错误。
解决方案:让TypeScript识别keys是Person的合法键数组
只需要把keys的类型从宽泛的string[]修正为Array<keyof Person>(也就是Person所有键的联合类型数组),就能让TypeScript确认每个prop都是合法的属性名。
修正后的完整代码示例
interface Person { eyeColor: string, hairLength: number, } const my: Person = { eyeColor: 'blue', hairLength: 0, }; // 关键点:将keys断言为keyof Person的数组,而非string数组 const keys = Reflect.ownKeys(my) as Array<keyof Person>; // 尝试4:现在可以正常访问属性了 keys.forEach((prop) => console.log(my[prop])) // 尝试5:pluck函数也能正常工作 const pluck = <T, P extends keyof T>(obj: T, prop: P): T[P]|undefined => obj[prop] keys.forEach((prop) => console.log(pluck(my, prop))) // 尝试6:解构也不再报错 keys.forEach((prop) => { const { [prop]: result } = my; return result })
补充说明
- 如果用
Object.keys替代Reflect.ownKeys,同样需要做类型断言,因为Object.keys默认返回string[]:const keys = Object.keys(my) as Array<keyof Person>; - 不建议给
Person加[key: string]: string | number这类索引签名——这会破坏Person接口的类型安全性,TypeScript将无法检查你是否访问了不存在的属性,违背了你定义接口的初衷。
内容的提问来源于stack exchange,提问作者kalisjoshua
相关产品推荐
相关产品推荐

