如果我使用这样的东西

type T0 = {p0: string, +p1?: string};
type T1 = {p0: string, p1: string};

function F0(a: T0) {}
function F1(a: T1) {
    F0(a);
}


flow try

一切正常:T0.p1是协变的,没有错误。

但。如果我需要一个类型数组

type T0 = {p0: string, +p1?: string};
type T1 = {p0: string, p1: string};

function F0(a: T0[]) {}
function F1(a: T1[]) {
    F0(a);
}


flow try

它抱怨“协变属性p1与不变用法不兼容”。
我不知道为什么会这样

最佳答案

有了这种类型的签名,您将无法阻止任何事情

function F0(a: T0[]) {
  a.push({ p0: "" });
}


F0的类型签名中有效,但在F1的类型签名中无效。

这给您两个选择。

使用协变数组类型$ReadOnlyArray,因此Flow知道您不会在数组中添加项目:

type T0 = {p0: string, +p1?: string};
type T1 = {p0: string, p1: string};

function F0(a: $ReadOnlyArray<T0>) {}
function F1(a: T1[]) {
    F0(a);
}


让泛型中的F1类型流经F0,因此Flow知道对象的实际类型。

type T0 = {p0: string, +p1?: string};
type T1 = {p0: string, p1: string};

function F0<T: T0>(a: Array<T>) {}
function F1(a: T1[]) {
    F0(a);
}

09-25 16:30