类型A不能分配给带有typescript 2.8条件类型的类型B.

Emm*_*ery 7 typescript

这实际上是对打字稿2.8的后续排除:可以增加"分区"类型吗? - 我在代码中引入条件类型时遇到问题.

请注意,条件类型是typescript 2.8的新类型,因此目前必须使用typescript 2.8rc构建.

我将当前的问题减少到这个非常小的测试用例:

export class Option<T> {
    toVector(): Vector<T> {
        return <any>undefined;
    }
}

interface Seq<T> {
    tail(): Option<Seq<T>>;
}

class Vector<T> implements Seq<T> {

    tail(): Option<Vector<T>> {
        return <any>undefined;
    }

     // the next line breaks the compilation
    partition2<U extends T>(predicate:(v:T)=>v is U): [Vector<U>,Vector<Exclude<T,U>>];
    partition2(predicate:(x:T)=>boolean): [Vector<T>,Vector<T>];
    partition2<U extends T>(predicate:(v:T)=>boolean): [Vector<U>,Vector<any>] {
        return <any>undefined;
    }
}
Run Code Online (Sandbox Code Playgroud)

新线是第一次重载partition2.如果你评论它,所有构建都很好.

如果你用--strict它编译它,它失败了一个相当令人困惑的构建错误:

t.ts(13,5): error TS2416: Property 'tail' in type 'Vector<T>' is not assignable to the same property in base type 'Seq<T>'.
  Type '() => Option<Vector<T>>' is not assignable to type '() => Option<Seq<T>>'.
    Type 'Option<Vector<T>>' is not assignable to type 'Option<Seq<T>>'.
      Types of property 'toVector' are incompatible.
        Type '() => Vector<Vector<T>>' is not assignable to type '() => Vector<Seq<T>>'.
          Type 'Vector<Vector<T>>' is not assignable to type 'Vector<Seq<T>>'.
            Types of property 'tail' are incompatible.
              Type '() => Option<Vector<Vector<T>>>' is not assignable to type '() => Option<Vector<Seq<T>>>'.
                Type 'Option<Vector<Vector<T>>>' is not assignable to type 'Option<Vector<Seq<T>>>'.
                  Types of property 'toVector' are incompatible.
                    Type '() => Vector<Vector<Vector<T>>>' is not assignable to type '() => Vector<Vector<Seq<T>>>'.
                      Type 'Vector<Vector<Vector<T>>>' is not assignable to type 'Vector<Vector<Seq<T>>>'.
                        Types of property 'tail' are incompatible.
                          Type '() => Option<Vector<Vector<Vector<T>>>>' is not assignable to type '() => Option<Vector<Vector<Seq<T>>>>'.
                            Type 'Option<Vector<Vector<Vector<T>>>>' is not assignable to type 'Option<Vector<Vector<Seq<T>>>>'.
                              Types of property 'toVector' are incompatible.
                                Type '() => Vector<Vector<Vector<Vector<T>>>>' is not assignable to type '() => Vector<Vector<Vector<Seq<T>>>>'.
                                  Type 'Vector<Vector<Vector<Vector<T>>>>' is not assignable to type 'Vector<Vector<Vector<Seq<T>>>>'.
                                    Types of property 'tail' are incompatible.
                                      Type '() => Option<Vector<Vector<Vector<Vector<T>>>>>' is not assignable to type '() => Option<Vector<Vector<Vector<Seq<T>>>>>'.
                                        Type 'Option<Vector<Vector<Vector<Vector<T>>>>>' is not assignable to type 'Option<Vector<Vector<Vector<Seq<T>>>>>'.
                                          Types of property 'toVector' are incompatible.
                                            Type '() => Vector<Vector<Vector<Vector<Vector<T>>>>>' is not assignable to type '() => Vector<Vector<Vector<Vector<Seq<T>>>>>'.
                                              Type 'Vector<Vector<Vector<Vector<Vector<T>>>>>' is not assignable to type 'Vector<Vector<Vector<Vector<Seq<T>>>>>'.
                                                Type 'Vector<Vector<Vector<Seq<T>>>>' is not assignable to type 'Vector<Vector<Vector<Vector<T>>>>'.
Run Code Online (Sandbox Code Playgroud)

我真的不知道该怎么做才能使这项工作:-(

jca*_*alz 5

正如我在评论中提到的那样,这看起来像是编译器错误(或至少是设计限制)。我能找到的最小复制品是这样的:

interface A<T> {
    bat: B<A<T>>;
}

interface B<T> extends A<T> {
    bat: B<B<T>>;
    boom: true
}
Run Code Online (Sandbox Code Playgroud)

这里一切都还好。所有类型参数都位于协变位置,这意味着如果Y是的子类型X,则A<Y>是的子类型A<X>,并且B<Y>是的子类型B<X>。并且由于B<T>是的子类型A<T>,因此可以推断出B<B<T>>是的子类型B<A<T>>。因此,将bat属性的范围B缩小B<A<T>>到可以B<B<T>>


现在看看当我们将条件类型(不会立即求值)添加到时会发生什么B

interface A<T> {
    bat: B<A<T>>;
}
interface B<T> extends A<T> {
//        ^ error
// Interface 'B<T>' incorrectly extends interface 'A<T>'.
    bat: B<B<T>>;

    boom: T extends any ? true : true
}
Run Code Online (Sandbox Code Playgroud)

它爆炸了。 boom无疑仍将是type true,但是以某种方式推迟的条件类型会引起麻烦。从错误中,很明显的是,编译器追击是否B<T>是兼容A<T>通过检查是否B<B<T>>是兼容B<A<T>>通过检查是否B<B<B<T>>>是兼容B<B<A<T>>>的...嗯哦。

因此,类型检查器中存在某种无限回归,可以尽早解决……这很好,因为否则编译器将挂起。但是,当它捞出它决定B<T>兼容A<T>,这是对我们有害的(虽然像“拯救成功”的规则可能是太糟糕)。


因此,我的建议是做您所做的事情并将问题提交到GitHub中。我们将在那里看到他们的评论。

我不确定是否有任何真正简单的解决方法。如果找到答案,我将对其进行编辑。

祝好运!