流数组的多态性和子类型

时间:2019-11-08 16:17:45

标签: javascript flowtype

我无法像使用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可以通过指示people中的Workplace数组将包含Person的子类型来正确实现此目的。

interface Workplace {
    people:Array<? extends Person>; // PSUEDO CODE: This is how Java supports subtypes
}

我无法在Flow中找到类似的机制。流程在此处讨论方差:https://flow.org/en/docs/lang/variance/#toc-covariancehttps://flow.org/en/docs/lang/depth-subtyping/

以下建议应该起作用。

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

但是此语法失败。

在Flow中,有没有一种方法可以声明数组协变类型?

1 个答案:

答案 0 :(得分:3)

流量差异需要一些时间来适应。正如您所提到的,核心问题是,如果

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