考虑以下代码:
interface MyInterface {
foo: string
bar: string
baz: string
}
const myObj: MyInterface = {
foo: "foo",
bar: "bar",
baz: "baz"
};
Object.keys(myObj).forEach(obj => {
obj = myObj[obj];
});
启用严格模式时,出现此错误:TS7017:元素隐式具有“ any”类型,因为类型“ MyInterface”没有索引签名。
最简单的解决方案似乎是:
interface MyInterface {
[key: string]: string;
foo: string
bar: string
baz: string
}
但是,这将打开MyInterface对象中的所有字符串属性。
然后我正在考虑使用映射类型:
type ValidEnteries = "foo" | "bar" | "baz";
type Alternative = {
[key in ValidEnteries]: string
}
虽然这对我来说似乎是正确的,但是原来的问题返回时缺少索引签名。
是否可以同时具有索引签名并将对象限制为一定数量的属性?
答案 0 :(得分:1)
如果只想获取接口的现有属性,则不需要索引签名。您可以使用字符串为任何对象建立索引,只要该字符串是该对象的已知键即可。如此有效:
myObj['bar'] // 'bar' can be checked as a key of MyInterface so it's ok
问题是Object.keys(myObj)
返回string[]
而不是Array<keyof T>
。最简单的解决方案是使用类型断言来让编译器知道keys
的返回是MyInterface
的键数组
Object.keys(myObj).forEach(obj => {
let d = myObj[obj as keyof MyInterface];
});
// OR
(Object.keys(myObj) as Array<keyof MyInterface>).forEach(obj => {
let d = myObj[obj];
});
或者,如果您对始终返回keys
的{{1}}函数感到满意,则可以扩展全局声明
Array<keyof T>