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

最近在前端项目中遇到在用字符串当对象的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
     }
 }
  • 21
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: 元素隐式具有 "any" 类型,是因为在 TypeScript 中,如果一个对象没有明确指定类型,那么它的类型就是 "any"。在这种情况下,如果我们尝试使用一个类型为 "string" 的表达式索引这个对象,TypeScript 就会报错,因为 "string" 类型不能用于索引类型。因此,为了避免这种错误,我们需要明确指定对象的类型,或者使用类型断言来告诉 TypeScript 我们知道这个对象的类型是什么。 ### 回答2: 在 TypeScript 中,元素隐式具有 "any" 类型,原因是因为如果我们声明数组时没有指定数组内元素类型TypeScript 就无法确定数组内元素类型。 例如,如果我们声明了一个空数组变量 arr,但是并没有在声明时指定 arr 变量的类型,那么 TypeScript 就不知道这个数组的元素类型是什么。 在使用元素时,如果我们尝试使用类型为 "string" 的表达式来做数组索引,就会出现问题,因为这样的表达式不能用作索引类型。 因此,为了避免这种情况,TypeScript 就将元素隐式指定为 "any" 类型,这样在使用元素时,就可以使用任何类型表达式来做索引,从而避免了出现类型错误的情况。 需要注意的是,虽然 TypeScript元素隐式指定为 "any" 类型,但是我们可以在声明数组时,显式指定数组内元素类型,这样就可以让 TypeScript 知道数组内元素的具体类型,从而更好地检查代码的类型安全性。 ### 回答3: 在 TypeScript 中,元素类型默认是 "any" 类型。这意味着我们可以将任何类型的值添加到数组或对象中,而不需要对其类型进行任何限制。而索引类型是一种特殊的类型,在 TypeScript 中,它可以用于对象或数组的索引访问,例如 obj[key] 或者 arr[index]。 如果我们尝试对一个 "string" 类型表达式进行索引访问,就会出现类型错误。因为 "string" 类型表达式不能用于索引类型,因此 TypeScript 编译器无法确定我们要访问对象或数组中的哪个元素,这也就导致了类型错误。 因此,元素类型应该被隐式指定为 "any" 类型,这样就可以将任何类型的值添加到数组或对象中,而不会出现类型错误。但是,在实际开发中,为了让代码更加可读和维护,我们应该尽量指定元素的具体类型,这能够减少代码错误,并且在之后的开发过程中能够更容易地维护和修改代码。 总结:元素隐式具有 "any" 类型,因为类型为 "string" 的表达式不能用于索引类型。在实际开发中,应该尽量指定元素的具体类型,以提高代码可读性、减少代码错误和更容易地维护和修改代码。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值