TypeScript报错:string类型无法索引AccountReceivedProps类型求解决
解决TypeScript遍历Object.keys时无法索引自定义类型的问题
问题本质
TypeScript里Object.keys()的返回类型固定是string[]——这是因为JavaScript允许对象存在继承来的额外键,TS为了类型安全,不会自动把它窄化为keyof AccountReceivedProps或AccountTypes。哪怕你明确知道对象的键全是AccountTypes,TS依然会做保守处理,导致用string类型变量索引AccountReceivedProps时触发类型错误。
解决方案
方案1:直接类型断言
把Object.keys(accountProps)断言为合法的键数组类型,这样map里的account会自动推断为keyof AccountReceivedProps(和AccountTypes等价):
(Object.keys(accountProps) as Array<keyof AccountReceivedProps>).map((account) => { return { col0: account, col1: `£ ${accountProps[account].total.toFixed(2)}`, col2: `£ ${(accountProps[account].total * (accountProps[account].annualRate / 100)).toFixed(2)}`, } })
也可以直接断言为AccountTypes[],效果完全一致:
(Object.keys(accountProps) as AccountTypes[]).map((account) => { // 逻辑同上 })
方案2:封装类型安全的keys工具函数
如果需要多次处理类似场景,封装复用函数更优雅,避免重复写断言:
// 工具函数:获取对象的键,返回类型为keyof T的数组 function getTypedKeys<T extends object>(obj: T): Array<keyof T> { return Object.keys(obj) as Array<keyof T>; } // 使用示例 getTypedKeys(accountProps).map((account) => { return { col0: account, col1: `£ ${accountProps[account].total.toFixed(2)}`, col2: `£ ${(accountProps[account].total * (accountProps[account].annualRate / 100)).toFixed(2)}`, } })
为什么直接给map参数指定类型没用?
你之前尝试在map((account: AccountTypes) => {})里指定参数类型无效,是因为Object.keys()返回的是string[],TS无法把string类型元素直接赋值给AccountTypes类型变量。必须先把整个数组的类型断言为合法的键数组,才能让map的参数自动推断出正确类型。
内容的提问来源于stack exchange,提问作者Ben Kemp
相关产品推荐
相关产品推荐

