Typescript 如何在不打开接口的情况下设置索引签名

Typescript 如何在不打开接口的情况下设置索引签名,typescript,index-signature,Typescript,Index Signature,考虑以下代码: 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

考虑以下代码:

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
}
虽然在我看来这似乎是正确的,但最初的问题是缺少索引签名


有没有办法既拥有索引签名,又将对象限制为一定数量的属性?

如果您只想获取接口的现有属性,则不需要索引签名。只要字符串是对象的已知键,就可以使用字符串索引任何对象。所以这是可行的:

 myObj['bar'] // 'bar' can be checked as a key of MyInterface so it's ok 
问题是
Object.keys(myObj)
返回
string[]
而不是
Array
。最简单的解决方案是使用类型断言让编译器知道
键的返回是
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];
});
declare global { /// Needed if you are in a module otherwise omit this and the closing }
    interface ObjectConstructor {
        keys<T extends object>(o: T) : Array<keyof T>
    }
}

// Now works without any extra casting 
Object.keys(myObj).forEach(obj => {
    let d = myObj[obj];
});