如何在不打开界面的情况下设置索引签名
How to set index signature without opening up the interface
考虑这段代码:
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-objects 中的任何字符串属性。
然后我在考虑改用映射类型:
type ValidEnteries = "foo" | "bar" | "baz";
type Alternative = {
[key in ValidEnteries]: string
}
虽然这对我来说似乎是正确的,但原始问题 returns 缺少索引签名。
有没有办法既有索引签名,又能限制对象的属性数量?
如果您只想获取接口的现有属性,则不需要索引签名。您可以使用字符串索引任何对象,只要该字符串是对象的已知键即可。所以这有效:
myObj['bar'] // 'bar' can be checked as a key of MyInterface so it's ok
问题是 Object.keys(myObj)
returns string[]
而不是 Array<keyof T>
。最简单的解决方案是使用类型断言让编译器知道 keys
的 return 是 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
函数总是 returning Array<keyof T>
感到满意,您可以扩展全局声明
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];
});
考虑这段代码:
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-objects 中的任何字符串属性。
然后我在考虑改用映射类型:
type ValidEnteries = "foo" | "bar" | "baz";
type Alternative = {
[key in ValidEnteries]: string
}
虽然这对我来说似乎是正确的,但原始问题 returns 缺少索引签名。
有没有办法既有索引签名,又能限制对象的属性数量?
如果您只想获取接口的现有属性,则不需要索引签名。您可以使用字符串索引任何对象,只要该字符串是对象的已知键即可。所以这有效:
myObj['bar'] // 'bar' can be checked as a key of MyInterface so it's ok
问题是 Object.keys(myObj)
returns string[]
而不是 Array<keyof T>
。最简单的解决方案是使用类型断言让编译器知道 keys
的 return 是 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
函数总是 returning Array<keyof T>
感到满意,您可以扩展全局声明
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];
});