Typescript元素在循环中隐式具有any for…类型
我有一个从JSON文件导入的JSON对象,其resolveJsonModule:true。 该对象如下所示:Typescript元素在循环中隐式具有any for…类型,typescript,for-in-loop,object-property,Typescript,For In Loop,Object Property,我有一个从JSON文件导入的JSON对象,其resolveJsonModule:true。 该对象如下所示: "myobject": { "prop1": "foo", "prop2": "bar" } 因此,它的类型如下所示: "myobject": { "prop1": "foo", "prop2": "bar" } myobject:{prop1:string,prop2:string} 这很好,但是当我尝试使用for…in循环时 对于myobject中的常量键{ 控制
"myobject": {
"prop1": "foo",
"prop2": "bar"
}
因此,它的类型如下所示:
"myobject": {
"prop1": "foo",
"prop2": "bar"
}
myobject:{prop1:string,prop2:string}
这很好,但是当我尝试使用for…in循环时
对于myobject中的常量键{
控制台.logmyobject[键]
}
我得到这个错误:
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; }'.
我理解这意味着迭代器键的类型为string,而不是“prop1”|“prop2”类型。但是我不明白迭代器为什么没有得到这种类型,因为我正在显式地遍历myobject的属性名。我是否错过了启用此行为的tsconfig属性?
我不想这样做:
for (const key in myobject) {
console.log(myobject[key as 'prop1' | 'prop2'])
}
因为:
我可能会在将来添加新的属性;和
这似乎有点骗人,我觉得有更好的办法。
如果希望对象将来是动态的,请创建如下模型
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}`)
});
}
}
更好的方法是:
for (const key in myobject) {
console.log(myobject[key as keyof typeof myobject])
}
这样,当您添加属性或将其重命名时,它不会中断。在循环中键入…的三种解决方案,我知道: 1.类型断言 A将强制将关键点类型缩小为myobject关键点: 2.显式声明键变量 for in循环中的键变量,我们可以在外部声明它:
let key: keyof typeof myobject // add this declaration
for (key in myobject) {
console.log(myobject[key]) // works
}
3.仿制药
为什么这是必要的?
在一个for…in循环中的键将通过设计实现。这是由于TypeScript的作用:只有在运行时才知道确切属性的键形状,编译器无法静态分析,编译时对象上存在哪些属性。缩小到myobject属性的键类型将使for…in循环成为不安全的操作类型
更多信息
注意:一些链接资源讨论Object.keys,这与相同的论证是一致的
-瑞安·卡瓦诺
-也提到…在
链接到大量重复问题
Anders Hejlsberg著:
我对此表示怀疑。对于x中的var k,其中x是某种类型的T,只有当x的确切类型是T时,才可以安全地说k是keyof T类型。如果x的实际类型是T的子类型,正如我们的赋值兼容性规则所允许的那样,您将看到k中的值不是keyof T类型
由于这是一个项目,您无法通过for loop访问它,只需使用myobject.prop1获取值我明白您的意思,但我不希望重建依赖于此关键值对象的整个基础设施:我可能在未来的项目中使用此项
function foo<T>(t: T) {
for (const k in t) {
console.log(t[k]) // works
}
}
foo(myobject)