这实际上是对打字稿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)
我真的不知道该怎么做才能使这项工作:-(
正如我在评论中提到的那样,这看起来像是编译器错误(或至少是设计限制)。我能找到的最小复制品是这样的:
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中。我们将在那里看到他们的评论。
我不确定是否有任何真正简单的解决方法。如果找到答案,我将对其进行编辑。
祝好运!
| 归档时间: |
|
| 查看次数: |
1555 次 |
| 最近记录: |