Я думаю, что большая проблема в том, что 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
) в случае изменения свойств объекта.