流量相当于Java通配符?

Flow equivalent to Java Wildcard?

在 Flow 中是否有等同于 Java's Wildcards 的内容?

这是我一直在测试的示例代码:


type InterfaceType = {
    var1 : number,
};

type ActualType = InterfaceType & {
    var2 : string,
};

type InterfaceGenericType<T : InterfaceType> = {
    var3 : T,
}

type ActualGenericType = InterfaceGenericType<ActualType> & {

}


class State<T : InterfaceGenericType<InterfaceType>> {

    prop : T;

    constructor(arg : T) : State<T> {
        this.prop = arg;
        return this;
    }
}


let actual : ActualType = {
    var1: 1,
    var2: "two",
};

let actualGeneric : ActualGenericType = {
    var3 : actual,
}

let s2 = new State(actualGeneric);

这是我遇到的流程错误:

    40: let s2 = new State(actualGeneric);
                           ^ Cannot call `State` with `actualGeneric` bound to `arg` because property `var2` is missing in `InterfaceType` [1] but exists in object type [2] in property `var3`.
        References:
        20: class State<T : InterfaceGenericType<InterfaceType>> {
                                                 ^ [1]
        7: type ActualType = InterfaceType & {
                                             ^ [2]

我知道我可以通过以下方式解决这个问题: class State<I : InterfaceType, T : InterfaceGenericType<I>> { 但我试图不必声明这两种类型。

我们可以 trim 稍微降低您的代码以删除 class:

type InterfaceType = { var1: number };
type ActualType = InterfaceType & { var2: string, };

type InterfaceGenericType<T : InterfaceType> = {
    var3: T,
};

let actual: ActualType = {
    var1: 1,
    var2: "two",
};

let actualGeneric: InterfaceGenericType<ActualType> = {
    var3: actual,
};

let v: InterfaceGenericType<InterfaceType> = actualGeneric;

我无法与 Java 通话,因为我不知道,但我可以告诉您如何解决此问题。如果我们查看此代码的错误:

17: let v: InterfaceGenericType<InterfaceType> = actualGeneric;
                                                 ^ Cannot assign `actualGeneric` to `v` because property `var2` is missing in `InterfaceType` [1] but exists in object type [2] in type argument `T` [3].
    References:
    17: let v: InterfaceGenericType<InterfaceType> = actualGeneric;
                                    ^ [1]
    2: type ActualType = InterfaceType & { var2: string, };
                                         ^ [2]
    4: type InterfaceGenericType<T : InterfaceType> = {
                                 ^ [3]

核心问题是 v 的类型 InterfaceGenericType<InterfaceType> 例如允许你做

v.var3 = { var1: 42 };

因为那是一个有效的 InterfaceType 对象。 不是 有效的 ActualType 对象,但是通过将 actualGeneric 分配给 v,您实际上已经删除了该类型信息,这意味着如果您的代码按原样被允许,分配将破坏您的 actualGeneric 对象的类型。

解决这个问题的方法是通过更改

告诉 Flow var3 属性 是只读的
var3: T,

成为

+var3: T,