流:计算属性。类型为类时在...中找不到可索引的签名

时间:2019-01-12 19:13:54

标签: javascript ecmascript-6 flowtype

在这种情况下如何解决错误(使用类作为类型):

/* @flow */

class Person {
  name: string;
  age: number;
}

const person: Person = new Person();
person.name = 'Bob';
person.age = 25;

['name', 'age'].forEach(key => {
  if(person[key]) {
    console.log(person[key]);
  }
});

错误指向person[key]并显示:

  

无法获得person[key],因为缺少索引器属性   Person

在类似情况下(可能是不同的流版本),它说:

  

计算属性。在Person

中找不到可索引的签名

1 个答案:

答案 0 :(得分:1)

我认为更大的问题是Array.prototype.forEach具有类型

forEach(callbackfn: (value: T, index: number, array: $ReadOnlyArray<T>) => any, thisArg?: any): void;

https://github.com/facebook/flow/blob/3baafb0f2191353cd896d6fe087aea535bc8606e/lib/core.js#L211

您可以看到value参数的类型为T,该类型由数组中元素的类型确定。在您的情况下,Flow(很可能)假设数组['name', 'age']的类型为string[]。因此,类型T设置为string

现在,当您尝试访问person[key]时,Flow会抱怨您缺少索引器属性。这是正确的,因为您尝试在string实例上使用通用的Person访问。即使删除条件后,该问题仍然存在,这表明Flow无法将string类型精简为'name''age'之一。

如果Flow可以提炼出这样的东西,那就太好了

/* @flow */

class Person {
  name: string;
  age: number;
}

const person: Person = new Person();
person.name = 'Bob';
person.age = 25;

['name', 'age'].forEach(key => {
  if (key === 'name') {
    console.log(person[key]);
  }
});

不一定是因为它有用,而是因为它是如此明确,并且在那时应该是安全的访问。

我将尝试避免使用遍历属性列表的循环来获取/设置对象的属性,因为Flow尚未处理类似于元组的细微差别。另外,如果对象的属性发生更改,则遍历对象本身(例如Object.keys)更具前瞻性。