最优雅解决typescript报错:“元素隐式具有 “any“ 类型,因为类型为 “string“ 的表达式不能用于索引类型”

百科知识2025-04-272

最近在前端项目中遇到在用字符串当对象的key时报错,报错信息如下: “元素隐式具有 “any” 类型,因为类型为 “string” 的表达式不能用于索引类型” 在类型 XXX 上找不到具有类型为 “string” 的参数的索引签名。

搜索了一圈解决方案,没一个特别优雅的。

方案一,修改tsconfig

是修改,加下面这行参数屏蔽检查,从而不报错。

"suppressImplicitAnyIndexErrors":true,

方案二,写一个函数转类型
export function isValidKey(key: string | number | symbol , object: object): key is keyof typeof object {
return key in object;
}

for (const key in obejct) {
if(isValidKey(key,obejct)){
// 处理...
obejct[key]
....
}
}

以上两种特别不优雅,非常不喜欢。在此我写一个比较优雅可靠的解决方法。

方案三:定义一个string作为key的类型
type stringKey = Record<string, boolean>
const accessDict: stringKey = {
create: false, // 创建
receive: false, // 接收
...
}

for (const i of AccessList) {
accessDict[i.authName] = true
}

写一个类型,表明key是字符串,value要看各位自己的需要定义。 我的项目中value是boolean,所以写boolean。

后面再用字符串当key遍历对象,typescript就不会报错了! 当然,如果仅仅为了解决报错,不用额外写一个类型,直接给变量注明类型即可:

const accessDict: Record<string, boolean> = {
create: false, // 创建
receive: false, // 接收
...
}

for (const i of AccessList) {
accessDict[i.authName] = true
}

遍历特定类型的对象

假定有一个对象类型如下:

type Count = {
receive: number // 待接收数
update: number // 待更正数
conduct: number // 待处理数
finish: number // 待销单数
check: number // 待审核数
notice: number // 待签到通知
}

现在有这样一个需求,统计该类型的对象中有几个属性的值大于0

const test: Count = {
receive: 1,
update: 2,
conduct: 0,
finish: 1,
check: 3,
notice: 0,
}

那么该怎么写代码比较优雅呢?逐个写if语句判断有点傻,直接for in循环会报错! typescript比较优雅的写法如下:

let cnt = 0
let key: keyof Count
for (key in test) {
if (test[key] > 0) {
cnt += 1
}
}