Flow 数组的多态性和子类型

Polymorphism and subtypes for Flow arrays

我无法像在 Java 等另一种语言中那样使用 Flow 泛型在数组中使用多态子类型。

考虑以下因素。

interface Person {
    name:string;
}

class Employee implements Person {
    name:string;
    badge:string;
}

interface Workplace {
    people:Array<Person>;
}

class MyOffice implements Workplace {
    people:Array<Employee>;  // ERROR: Incompatible with Workplace.people
}

这在 Java 中也会失败;但是 Java 有一种方法可以通过指示 Workplace 中的 people 数组将包含 Person.

的子类型来正确实现这一点
interface Workplace {
    people:Array<? extends Person>; // PSUEDO CODE: This is how Java supports subtypes
}

我没能在 Flow 中找到类似的机制。 Flow 在这里讨论方差:https://flow.org/en/docs/lang/variance/#toc-covariance and https://flow.org/en/docs/lang/depth-subtyping/

这表明以下应该有效。

interface Workplace {
    people:Array<+Person>;
}

但是这个语法失败了。

在 Flow 中有声明数组协变类型的方法吗?

Flow 的变化需要一些时间来适应。正如您所提到的,核心的是如果

这两个操作将无效
interface Workplace {
    people:Array<Person>;
}

按原样被允许:

var workplace: Workplace = new MyOffice();

// Not an `Employee`, can't allow adding to array
workplace.people.push(new SomeOtherPersonImpl()); 

// Not an `Employee`, can't allow replacing array.
workplace.people = [new SomeOtherPersonImpl()];

要获得这两个属性,我们需要

  1. people 数组设为只读 ($ReadOnlyArray)。
  2. people 属性 设为只读。 (你提到的+

结合这些,你最终得到:

interface Workplace {
    +people: $ReadOnlyArray<Person>;
}

(Flow Try Example)