首页 > 解决方案 > 流:计算属性。当类型为类时,在...中找不到可索引签名

问题描述

在这种情况下如何修复错误(保持使用类作为类型):

/* @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

标签: javascriptecmascript-6flowtype

解决方案


我认为更大的问题是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参数有 type T,由数组中元素的类型决定。在您的情况下, Flow (很可能)假设数组的类型['name', 'age']string[]. 因此,类型T设置为string

现在,当您尝试访问时person[key],Flow 会抱怨您缺少索引器属性。这是准确的,因为您正在尝试对实例使用通用string访问。Person即使在删除条件后,此问题仍然存在,这暗示 Flow 无法将string类型细化为'name'and之一'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另外,在对象的属性发生变化的情况下,循环遍历对象本身(例如,)更具前瞻性。


推荐阅读