小编典典

在启用 noImplicitAny 标志编译打字稿时,如何防止错误“对象类型的索引签名隐含地具有'任何'类型”?

all

我总是用标志 –noImplicitAny 编译 Typescript。这是有道理的,因为我希望我的类型检查尽可能严格。

我的问题是使用以下代码出现错误Index signature of object type implicitly has an 'any' type

interface ISomeObject {
    firstKey:   string;
    secondKey:  string;
    thirdKey:   string;
}

let someObject: ISomeObject = {
    firstKey:   'firstValue',
    secondKey:  'secondValue',
    thirdKey:   'thirdValue'
};

let key: string = 'secondKey';

let secondValue: string = someObject[key];

需要注意的重要一点是,关键变量来自应用程序中的其他位置,并且可以是对象中的任何键。

我尝试通过以下方式显式转换类型:

let secondValue: string = <string>someObject[key];

或者我的情况是不可能的--noImplicitAny


阅读 86

收藏
2022-03-29

共1个答案

小编典典

添加索引签名将使 TypeScript 知道类型应该是什么。

在你的情况下,那将是[key: string]: string;

interface ISomeObject {
    firstKey:      string;
    secondKey:     string;
    thirdKey:      string;
    [key: string]: string;
}

但是,这也会强制所有属性类型与索引签名匹配。由于所有属性都是string有效的。

虽然索引签名是描述数组和“字典”模式的强大方式,但它们还强制所有属性与其返回类型匹配。

编辑:

如果类型不匹配,可以使用联合类型[key: string]: string|IOtherObject;

对于联合类型,最好让 TypeScript 推断类型而不是定义它。

// Type of `secondValue` is `string|IOtherObject`
let secondValue = someObject[key];
// Type of `foo` is `string`
let foo = secondValue + '';

虽然如果您在索引签名中有很多不同的类型,这可能会有点混乱。替代方法是any在签名中使用。[key: string]: any;然后你需要像上面那样转换类型。

2022-03-29