3

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

我在这里创建了一个代表问题的 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,而不是 type B

我怎样才能返回类型this,而不是声明foo()总是返回类型A

我试过这个:

在此处输入图像描述

但我收到此错误:

在此处输入图像描述

4

2 回答 2

6

你必须返回this使用多态的类型这个类型

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

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

这将允许

const b = new B();

b.foo().bar();
于 2017-11-25T21:52:46.817 回答
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;
  }

泛型

您不能使基类泛型,以返回 type T。您不能将类用作其自身类型参数的类型约束。您还有一个问题是A无法保证与Tthat extends兼容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();
于 2017-11-25T21:12:45.423 回答