Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript元素在循环中隐式具有any for…类型_Typescript_For In Loop_Object Property - Fatal编程技术网

Typescript元素在循环中隐式具有any for…类型

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中的常量键{ 控制

我有一个从JSON文件导入的JSON对象,其resolveJsonModule:true。 该对象如下所示:

"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)