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

How to return subtype from superclass method instead of superclass type

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

我创建了一个 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() 将 return 类型声明为 A,而不是类型 B.

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

我试过这个:

但是我得到这个错误:

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

过载

如果你想让 new C().foo().zoom() 版本工作,你可以实现它,同时仍然收到关于 bar() 错误的警告,下面的代码创建了一个兼容的重载 returns 是父类型的子类型 class:

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;
  }

泛型

您不能使基础 class 通用,以便 return 类型 T。您不能将 class 用作其自身类型参数的类型约束。您还遇到 A 无法保证与扩展 A.

T 兼容的问题

可以做的是引入一个接口,并在每个 class:

上使用它
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();

您必须 return 使用 polymorphic this typethis 类型。

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

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

这将允许

const b = new B();

b.foo().bar();