TypeScript - ts(7053):元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引

Posted

技术标签:

【中文标题】TypeScript - ts(7053):元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引【英文标题】:TypeScript - ts(7053) : Element implicitly has an 'any' type because expression of type 'string' can't be used to index 【发布时间】:2020-10-26 18:44:43 【问题描述】:

在 TypeScript 中,我声明一个这样的接口:

export default interface MyDTO 
    readonly num: string;
    readonly entitle: string;
    readonly trb: string;
    readonly ucr: string;
    readonly dcr: string;
    readonly udm?: string;
    readonly ddm?: string;

使用函数,我想访问属性的值,其名称包含在变量中。

private doSomething(dto: MyDTO, property: string): any 
    let label: any;

    if (['dcr', 'ddm'].includes(property)) 
        label = doSomethingElse(dto[property]);
     else 
        label = dto[property];
    
    
    return label;

不幸的是,TypeScript 给了我以下错误信息:

元素隐含地具有“任何”类型,因为类型的表达式 “字符串”不能用于索引类型“MyDTO”。没有索引签名 在 type 上找到了“string”类型的参数 'MyDTO'.ts(7053)

有人有想法吗?

谢谢

【问题讨论】:

这能回答你的问题吗? How do I prevent the error "Index signature of object type implicitly has an 'any' type" when compiling typescript with noImplicitAny flag enabled? 【参考方案1】:

@mhodges,根据您的建议,这是我修改后的函数,它似乎运行良好。 但是在以下情况下,我必须添加“作为字符串”,否则会出现以下错误:

键入'字符串 | keyof V'不能用于索引类型'V'.ts (2536)

public getDefaultComparator(property: keyof V | string, v1: V, v2: V): number 
    let compareReturn = 0;
    if (v1.hasOwnProperty(property)) 
      const compareValue1 = v1[property as string];
      const compareValue2 = v2[property as string];
      if (compareValue1 > compareValue2) 
        compareReturn = 1;
       else if (compareValue1 < compareValue2) 
        compareReturn = -1;
      
    

    return compareReturn;
  

【讨论】:

【参考方案2】:

这是因为 MyDTO 已明确命名属性,但您使用通用字符串作为索引,因此 TypeScript 表示它不能保证将任何字符串传递给您的 doSomething 函数实际上会匹配您界面上的属性名称。

TypeScript 2.1 中引入的一个很好的解决方法是keyof。这允许您显式键入某些内容作为某个类/接口的键。

这将 A. 消除您看到的 TS 错误,并且 B. 还会检查以确保您的函数的任何调用者实际上传递了有效的密钥。

export default interface MyDTO 
    readonly num: string;
    readonly entitle: string;
    readonly trb: string;
    readonly ucr: string;
    readonly dcr: string;
    readonly udm?: string;
    readonly ddm?: string;


function doSomething(dto: MyDTO, property: keyof MyDTO): any 
    let label: any;

    if (['dcr', 'ddm'].includes(property)) 
        label = doSomethingElse(dto[property]);
     else 
        label = dto[property];
    
    
    return label;


doSomething(obj, "foo") // is a TS error
doSomething(obj, "num") // is valid

【讨论】:

这确实纠正了我的情况。但是我有一个特殊的情况,我在财产中的价值不是我的 DTO 的关键。这可以是一个简单的字符串,它允许我从我的 DTO 的属性中进行操作,但我不直接恢复我的对象的属性。例如: if (property === 'test') label = property.num + '-' + property.entitle; 。如何将 keyof 和类型字符串以及与类型无关的函数代码中的 keyof 结合起来? 我可以在对输入的类型进行测试之前做:if(typeof property === 'string')。 如何测试属性的值是否是我的对象的键?如果我测试我的对象的类型(类型字符串),我总是通过,即使它是我的对象的键。 @Answerrer 我不确定我是否理解这个问题。您能否使用此解决方案不适合您的完整示例更新您的帖子?您似乎想知道对象上的属性值是否也是对象的键? 救了我的培根。谢谢!

以上是关于TypeScript - ts(7053):元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引的主要内容,如果未能解决你的问题,请参考以下文章

TS7053:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“用户经济”

对接收动作类型的 TypeScript reducer 进行类型检查

如何在较新版本的打字稿中处理打字稿错误 Object.ts (7053)?

元素隐式具有“任何”类型,因为类型“窗口”没有索引签名?

react+ts 项目:引入antd select组件联动 ,ts7053ts2741报错解决

如何修复 Element 隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型?