Typescript中如何将string转为自定义接口的键类型以解决索引报错
TypeScript 接口索引报错解决方法
你遇到的报错是因为 Address_findUserAddress 是固定键的接口,TS 不允许用任意 string 类型的值直接索引该类型的对象,需要把 k.addressKey 的类型收窄为该接口的合法键,可按以下几种方案解决:
方案1:从类型定义根源约束(推荐)
这是最优方案,从源头保证 addressKey 一定是合法键:
- 先提取接口的合法键类型:
type AddressValidKey = keyof Address_findUserAddress // 等价于 "addressCity" | "addressCountry" | "addressFirstLine"
- 定义
addressAnswerKeys的元素类型,把addressKey字段约束为上面的合法键类型:
type AddressAnswerKeyItem = { answerKey: string addressKey: AddressValidKey } // 声明 addressAnswerKeys 时指定类型 const addressAnswerKeys: AddressAnswerKeyItem[] = [/* 你的原有配置 */]
改完之后不需要做任何额外处理,address[k.addressKey] 不会再报错。
方案2:临时类型断言
如果没法修改 addressAnswerKeys 的类型定义,可以用类型断言直接指定 k.addressKey 是合法键:
修改报错位置的代码为:
address[k.addressKey as keyof Address_findUserAddress]
完整的 reduce 写法如下:
const mappedAddress = addressAnswerKeys.reduce( (acc, k) => ({ ...acc, [k.answerKey]: address[k.addressKey as keyof Address_findUserAddress] ?? '' }), {} as Record<string, string> );
注意:你的接口字段类型是
string | null,如果一定要收窄为string可以加?? ''处理空值。
方案3:加类型守卫(类型+运行时双安全)
如果 k.addressKey 的值可能存在非法值,建议加类型守卫做运行时校验,避免出现意料之外的取值:
- 先定义类型守卫函数:
function isAddressValidKey(key: string): key is keyof Address_findUserAddress { return ['addressCity', 'addressCountry', 'addressFirstLine'].includes(key) }
- 在 reduce 里先做校验再取值:
const mappedAddress = addressAnswerKeys.reduce( (acc, k) => { if (isAddressValidKey(k.addressKey)) { acc[k.answerKey] = address[k.addressKey] ?? '' } return acc }, {} as Record<string, string> );
内容的提问来源于stack exchange,提问作者Amel Amcë Muminovic
相关产品推荐
相关产品推荐

