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

Ans*_*rer 6 javascript interface typescript

在 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

有人有想法吗?

谢谢

mho*_*ges 7

这样做的原因是因为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
Run Code Online (Sandbox Code Playgroud)