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

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

方案一,修改tsconfig

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

"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
     }
 }
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐