代码之家  ›  专栏  ›  技术社区  ›  jmindel

在typescript中识别接口和类之间的多态性

  •  2
  • jmindel  · 技术社区  · 6 年前

    我目前正在typescript(版本2.9.2)中处理一个项目,遇到了意外的多态行为。在Java和C_这样的语言中,接口和类一样定义多态行为,也就是说,在下面,同样正确的是 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 { /* ... */ }
    }
    

    编译器的返回类型似乎有问题 S someFunction() ,但根据我对多态性的理解, 器物 ,如果函数返回类型为 ,那么它还应该能够返回 . 尽管如此,有些东西应该是 ,因为接口不能实例化,并且只不过是类之间的无形协议或契约。如果 相反,如果是一个抽象类,多态行为的行为应该像我所期望的那样,但在库im构建的范围内,它似乎更适合于 作为一个接口。

    编译器在声明 某个函数() :

    [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
    

    部分问题似乎在于我在 . 如果我删除了构造函数定义,问题就解决了,但我需要该定义成为协议的一部分,协议的基本含义是 .

    考虑到我所期望的多态行为,我应该如何着手编写接口,或者应该改用抽象类?我该如何实现这种多态行为?

    1 回复  |  直到 6 年前
        1
  •  1
  •   artem    6 年前

    我需要这个定义作为协议的一部分 从根本上说是A型的

    不幸的是,在语言上没有这种支持。 Construct signature can not be a part of contract 声明要实现的类。 extends 只声明契约的实例部分,构造函数和静态方法是所谓 "static part" 而且没有办法宣布这方面的合同。

    typescript使用结构类型,因此实际上可以使用 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