如何在TypeScript中安全访问跨对象的未定义属性?
问题分析与解决方案
你遇到的TypeScript报错翻译为:
元素隐式拥有 'any' 类型,因为类型为 "foo" | "bar" 的表达式不能用于索引类型 '{ foo: string; }'。属性 'bar' 在类型 '{ foo: string; }' 上不存在。
原因是key是"foo" | "bar"的联合类型,当你用它去索引firstList时,TypeScript无法确定当前key是否属于firstList的键,所以抛出类型错误。以下是几种可行的解决方式:
1. 使用in操作符做类型守卫
这是最安全的方式,TypeScript会根据key in firstList的判断自动收窄类型,确保索引操作合法:
const firstList = { foo: "a value" } const secondList = { bar: "another value" } function getValue(key: keyof typeof firstList | keyof typeof secondList) { if (key in firstList) { return firstList[key] } return secondList[key] }
2. 类型断言明确索引合法性
通过类型断言告诉TypeScript当前key属于对应对象的键,适合你能确保逻辑正确性的场景:
const firstList = { foo: "a value" } const secondList = { bar: "another value" } function getValue(key: keyof typeof firstList | keyof typeof secondList) { let val = firstList[key as keyof typeof firstList] if (val != undefined) return val return secondList[key as keyof typeof secondList] }
3. 泛型结合Record类型适配多对象场景
如果后续需要扩展更多对象,这种方式更灵活,通过泛型约束和Record类型统一处理索引:
const firstList = { foo: "a value" } const secondList = { bar: "another value" } type CombinedKeys = keyof typeof firstList | keyof typeof secondList; type CombinedValues = typeof firstList[keyof typeof firstList] | typeof secondList[keyof typeof secondList]; function getValue<K extends CombinedKeys>(key: K): CombinedValues { return (firstList as Record<K, CombinedValues>)[key] ?? (secondList as Record<K, CombinedValues>)[key]; }
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

