如何从超类方法而不是超类类型返回子类型

时间:2017-11-25 21:03:29

标签: typescript generics typescript2.0 typescript-generics

我认为这是正确实现泛型的问题,但我不确定。

我在这里创建了一个表示问题的Github要点: https://gist.github.com/ORESoftware/66b72b4b85262d957cb03ad097e4743e

说我有这个超类:

  class A {

    foo(): A {
      return this;
    }

  }

和几个子类,例如,如下所示:

   class B extends A {

     bar(): B {
      return this;
     }

   }

所以如果我这样做

new B().foo().bar()

这将在运行时工作,但无法使用TypeScript编译。那是因为foo()将返回类型声明为A,而不是B类型。

如何返回this所属的类型,而不是声明foo()始终返回类型A

我试过了:

enter image description here

但是我收到了这个错误:

enter image description here

2 个答案:

答案 0 :(得分:3)

您必须使用polymorphic this type返回this的类型。

abstract class A {
    foo(): this {
        return this;
    }
}

class B extends A {
    bar(): this {
        return this;
    }
}

将允许

const b = new B();

b.foo().bar();

答案 1 :(得分:1)

我有两个例子,一个有重载,一个有通用接口。

过载

如果你想让new C().foo().zoom()版本工作,你可以实现这一点,同时仍然通过以下代码得到关于bar()错误的警告,这会产生一个兼容的重载,返回一个子类型父类中的类型:

class A {
  foo(): A {
    return this;
  }
}

class B extends A {
  foo(): B {
    return this;
  }

  bar(): B {
    return this;
  }
}

class C extends A {
  foo(): C {
    return this;
  }

  zoom(): C {
    return this;
  }
}

const result = new C().foo().zoom();

如果您的代码中的实际方法确实执行了您想要重用的内容,则可以调用super.foo() ...但是在不需要的示例代码中。

  foo(): C {
    const a = super.foo();
    // You still need to return this, as it is a C, not an A.
    return this;
  }

泛型

您不能使基类具有通用性,以便返回类型T。您不能在自己的类型参数中将类用作类型约束。您也遇到问题,A无法保证与T扩展A兼容。

可以做的是介绍一个界面,并在每个类上使用它:

interface Fooable<T> {
  foo(): T;
}

class A {
  foo(): any {
    return this;
  }
}

class B extends A implements Fooable<C> {
  bar(): B {
    return this;
  }
}

class C extends A implements Fooable<C> {
  zoom(): C {
    return this;
  }
}

const result = new C().foo().zoom();