Typescript基于条件扩展的条件类型的行为不符合预期

时间:2019-03-21 11:01:30

标签: typescript type-inference typescript-generics conditional-types

假设我们有这个示例:

class Base<T extends Base<T>> {}
class ClassA extends Base<ClassA> {}
class ClassB extends Base<ClassB> {}
type Condition = ClassA extends ClassB ? true : false;

基类有一个泛型参数,基本上说,从它派生的任何东西都应该使用它自己的类型作为模板。

然后,我们有2个类来自于上述基础。

最后,我创建了一个条件类型,该条件类型检查派生类是否彼此扩展。

令我惊讶的是,打字稿告诉我他们这样做,但是我认为这种情况应该是错误的。 ClassA未扩展ClassB,反之亦然。只有ClassA extends Base<ClassA>应该返回true。

这是打字稿的条件类型问题还是我缺少什么?在构建更复杂的条件类型时,我碰到了这个问题,同时也返回了意外的结果。

编辑:也不需要通用参数。即使这个例子也返回错误的结果:

class Base {}
class ClassA extends Base {}
class ClassB extends Base {}
type Condition = ClassA extends ClassB ? true : false;

1 个答案:

答案 0 :(得分:3)

Typescript使用结构化类型来最好地模拟Javascript鸭子类型的工作方式。这样做的好处是允许我们以静态类型的方式对许多Javascript场景进行建模。

问题是您永远不能忘记,当打字稿检查任何类型的兼容性(即使在条件类型中)时,它也没有像C#或Java那样检查名义继承,而是在检查结构子类型。

在您的示例中,由于所有类都是空的,因此它们在结构上等效于{},这意味着,ClassA确实扩展了ClassB,而ClassB扩展了{{ 1}},因为它们在结构上都是相同的类型。

将任何成员添加到类中后,私有成员可确保最大的不兼容性,因为另一个类(或接口)不能仅仅声明重新声明它们来模仿子类型。

ClassA