Typescript 的基于条件类型的扩展行为不符合预期
Typescript's conditional type based one extends behaves not as expected
假设我们有这个例子:
class Base<T extends Base<T>> {}
class ClassA extends Base<ClassA> {}
class ClassB extends Base<ClassB> {}
type Condition = ClassA extends ClassB ? true : false;
基础 class 有一个通用参数,基本上说,从它派生的任何东西都应该用它自己的类型模板化它。
然后我们有 2 个 class 派生自所述基础。
最后我创建了一个条件类型来检查派生的 classes 是否相互扩展。
令我惊讶的是打字稿告诉我他们这样做,但我认为这个条件应该是错误的。 ClassA
没有扩展 ClassB
,反之亦然。只有 ClassA extends Base<ClassA>
应该 return 为真。
这是打字稿条件类型的问题还是我遗漏了什么?我在构建更复杂的条件类型时遇到了这个问题,这也是 returning 意外结果。
编辑: 也不需要通用参数。即使这个例子 return 的错误结果:
class Base {}
class ClassA extends Base {}
class ClassB extends Base {}
type Condition = ClassA extends ClassB ? true : false;
Typescript 使用结构化类型来最好地模拟 Javascript 鸭子类型的工作方式。这样做的好处是允许我们以静态类型的方式对许多 Java 脚本场景进行建模。
问题是你永远不能忘记,当 typescript 检查任何类型的兼容性(即使在条件类型中)时,它不会像 C# 或 Java 那样检查名义继承,它会检查结构子类型。
在您的示例中,由于所有 class 都是空的,因此它们在结构上等同于 {}
,这意味着是的,ClassA
确实扩展了 ClassB
和 ClassB
extends ClassA
因为它们在结构上都是相同的类型。
将任何成员添加到 classes 中,这就会消失,私有成员确保最大的不兼容性,因为另一个 class(或接口)不能仅仅声明重新声明它们来模仿子类型。
class Base {}
class ClassA extends Base { private a: number}
class ClassB extends Base { private b: number}
type Condition = ClassA extends ClassB ? true : false; // false now
假设我们有这个例子:
class Base<T extends Base<T>> {}
class ClassA extends Base<ClassA> {}
class ClassB extends Base<ClassB> {}
type Condition = ClassA extends ClassB ? true : false;
基础 class 有一个通用参数,基本上说,从它派生的任何东西都应该用它自己的类型模板化它。
然后我们有 2 个 class 派生自所述基础。
最后我创建了一个条件类型来检查派生的 classes 是否相互扩展。
令我惊讶的是打字稿告诉我他们这样做,但我认为这个条件应该是错误的。 ClassA
没有扩展 ClassB
,反之亦然。只有 ClassA extends Base<ClassA>
应该 return 为真。
这是打字稿条件类型的问题还是我遗漏了什么?我在构建更复杂的条件类型时遇到了这个问题,这也是 returning 意外结果。
编辑: 也不需要通用参数。即使这个例子 return 的错误结果:
class Base {}
class ClassA extends Base {}
class ClassB extends Base {}
type Condition = ClassA extends ClassB ? true : false;
Typescript 使用结构化类型来最好地模拟 Javascript 鸭子类型的工作方式。这样做的好处是允许我们以静态类型的方式对许多 Java 脚本场景进行建模。
问题是你永远不能忘记,当 typescript 检查任何类型的兼容性(即使在条件类型中)时,它不会像 C# 或 Java 那样检查名义继承,它会检查结构子类型。
在您的示例中,由于所有 class 都是空的,因此它们在结构上等同于 {}
,这意味着是的,ClassA
确实扩展了 ClassB
和 ClassB
extends ClassA
因为它们在结构上都是相同的类型。
将任何成员添加到 classes 中,这就会消失,私有成员确保最大的不兼容性,因为另一个 class(或接口)不能仅仅声明重新声明它们来模仿子类型。
class Base {}
class ClassA extends Base { private a: number}
class ClassB extends Base { private b: number}
type Condition = ClassA extends ClassB ? true : false; // false now