流是否等同于Java通配符?

问题描述 投票:0回答:1

流程中是否有与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>> {但我试图不必同时声明这两种类型。

flowtype
1个回答
0
投票

我们可以稍微减少您的代码以删除该类:

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,
© www.soinside.com 2019 - 2024. All rights reserved.