javascript - 识别 Typescript 中接口(interface)和类之间的多态性

标签 javascript typescript oop interface polymorphism

我目前正在使用 TypeScript(版本 2.9.2)开发一个项目,遇到了意外的多态行为。在 Java 和 C# 中,接口(interface)和类一样定义多态行为——也就是说,在下面,item1 可以是类型 A 因为它可以是 B 类型,而 item2 可以是 C 类型 因为它可以是类型D:

interface A { }
class B implements A { }
class C { }
class D extends C { }

但在 TypeScript 中,情况似乎并非如此。我有大约以下设置:

interface A {
    new (str: string): Module;
    someFunction(str: string): A;
}

class B implements A {
    constructor(str: string) { /* ... */ }
    someFunction(str: string): B { /* ... */ }
}

编译器似乎对 BsomeFunction() 的返回类型有问题,但根据我对多态性的理解,因为 B 实现了 A,如果一个函数返回类型为 A 的东西,那么它也应该能够返回类型为 B 的东西。话虽如此,某些东西应该是“A 类型”是没有意义的,因为接口(interface)不能被实例化,并且只不过是类之间的无形协议(protocol)或契约。那么,如果 A 改为抽象类,那么多态行为应该如我所料——确实如此——但在我正在构建的库的范围内,这似乎是合理的A 更适合作为接口(interface)。

编译器特别给出的问题如下,声明BsomeFunction()行:

[ts]
Property 'someFunction' in type 'B' is not assignable to the same property in base type 'A'.
  Type '(str: string) => B' is not assignable to type '(str: string) => A'.
    Type 'B' is not assignable to type 'A'.
      Types of property 'someFunction' are incompatible.
        Type '(str: string) => B' is not assignable to type '(str: string) => A'.
(method) Project.B.someFunction(str: string): B

部分问题似乎在于我在 A 中声明了一个构造函数。如果我删除该构造函数定义,问题就解决了,但我需要该定义成为A 类型的基本含义协议(protocol)的一部分。

考虑到我期望的多态行为,我应该如何编写我的界面,或者我应该使用抽象类来代替?如何实现这种多态行为?

最佳答案

I need that definition to be part of the agreement of what it fundamentally means to be of type A

不幸的是,该语言不支持该功能。 Construct signature can not be a part of contract声明要实现的类。 extends 仅声明合约的实例部分,构造函数和静态方法是所谓的 "static part" 的一部分。并且没有办法为此声明契约(Contract)。

TypeScript 使用结构类型,因此您实际上可以在需要指定构造签名的接口(interface)时使用 B,但必须单独声明该接口(interface),并且每次都会检查一致性 B 就地使用,没有办法事先声明:

interface AConstructor {
    new (str: string): A;
}

interface A {
    someFunction(str: string): A;
}

class B implements A {
    constructor(str: string) { /* ... */ }
    someFunction(str: string): B { /* ... */ }
}

function f(cls: AConstructor) {
    const instance = new cls('hi');
    instance.someFunction('how are you?');
}

f(B);  // ok

关于javascript - 识别 Typescript 中接口(interface)和类之间的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51164402/

相关文章:

javascript - Angular ng-click 不适用于 ng-show

javascript - Cookie 在 Safari 中不起作用

javascript - 在javascript中迭代对象并通过键查找值

扩展类型属性的 Typescript 部分 [TS2322]

generics - Typescript 泛型约束扩展了其他泛型类型

javascript - MediaWiki 扩展中加载 js 不起作用

javascript - 检测 Facebook 分享成功?

允许转换为 sql 的 PHP 规范模式

c++ - 我的功能返回后需要休息一下吗?

php - 在继承层次结构中重载构造函数是否意味着需要组合?