我有一个从JSON文件(带有resolveJsonModule: true
)导入的JSON对象。
该对象看起来像这样:
"myobject": {
"prop1": "foo",
"prop2": "bar"
}
,因此它的类型如下:
myobject: { prop1: string, prop2: string }
这很好,但是当我尝试使用for...in
循环时,
for (const key in myobject) {
console.log(myobject[key])
}
我收到此错误:
TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ "prop1": string; "prop2": string; }'.
No index signature with a parameter of type 'string' was found on type '{ "prop1": string; "prop2": string; }'.
我知道这意味着迭代器key
的类型为string
,而不是类型为'prop1' | 'prop2'
。但是我不明白为什么迭代器没有得到这种类型,因为我明确地遍历了myobject
的属性名。我是否错过了启用此行为的tsconfig属性?
我不想这样做:
for (const key in myobject) {
console.log(myobject[key as 'prop1' | 'prop2'])
}
因为:
答案 0 :(得分:1)
如果您希望将来有一个动态对象,请创建这样的模型
interface PropertyItemModel {
propName: string;
propValue: string;
}
,在该组件中,您可以循环获取数据
export class AppComponent {
items: PropertyItemModel[] = [];
constructor() {
this.items = [
{ propName: "1", propValue: "foo" },
{ propName: "2", propValue: "bar" }]
this.items.forEach(item => {
console.log(`name: ${item.propName} - value: ${item.propValue}`)
});
}
}
答案 1 :(得分:1)
一种更好的方法是:
for (const key in myobject) {
console.log(myobject[key as keyof typeof myobject])
}
通过这种方式,添加属性或重命名它不会中断
答案 2 :(得分:0)
我不明白为什么迭代器没有得到这种类型,因为我明确地遍历了myobject的属性名称,
这是by design-在{。{1}}这样的for..in循环中,for (const key in myobject)
的类型为key
。编译器无法静态分析对象上确切具有的属性。属性键的确切形状仅在运行时才知道,因此他们决定将类型扩展为string
以保持完整性(类似于Object.keys
)。
唯一的例外是generic types:
string
除了像Shalom Peles一样进行强制转换外,您还可以在规避之前声明function foo<T>(t: T) {
for (const k in t) {
k // Extract<keyof T, string>
}
}
类型,使其不能在循环本身中输入:
key
更多信息: