我总是用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?
目前更好的解决方案是声明类型。就像
enum SomeObjectKeys {
firstKey = 'firstKey',
secondKey = 'secondKey',
thirdKey = 'thirdKey',
}
let someObject: Record<SomeObjectKeys, string> = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue',
};
let key: SomeObjectKeys = 'secondKey';
let secondValue: string = someObject[key];
TypeScript 2.1引入了优雅的方法来处理这个问题。
const key: (keyof ISomeObject) = 'secondKey';
const secondValue: string = someObject[key];
我们可以在编译阶段通过keyof关键字(参见changelog)访问所有对象属性名。
你只需要用keyof ISomeObject替换字符串变量类型。
现在编译器知道关键变量只允许包含来自ISomeObject的属性名。
完整的例子:
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: number;
}
const someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 3
};
const key: (keyof ISomeObject) = 'secondKey';
const secondValue: string = someObject[key];
// You can mix types in interface, keyof will know which types you refer to.
const keyNumber: (keyof ISomeObject) = 'thirdKey';
const numberValue: number = someObject[keyNumber];
typescriptlang.org上的实时代码(设置noImplicitAny选项)
进一步阅读,了解更多用法要点。
目前更好的解决方案是声明类型。就像
enum SomeObjectKeys {
firstKey = 'firstKey',
secondKey = 'secondKey',
thirdKey = 'thirdKey',
}
let someObject: Record<SomeObjectKeys, string> = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue',
};
let key: SomeObjectKeys = 'secondKey';
let secondValue: string = someObject[key];