如何强制调用`super.ngOnDestroy`

How to force call `super.ngOnDestroy`

我有一个摘要 class 有助于避免重复代码(取消订阅可观察对象),它看起来像:

export abstract class SubscriptionManagmentDirective implements OnDestroy {
  componetDestroyed = new Subject<void>()

  constructor() {}

  ngOnDestroy(): void {
    this.componetDestroyed.next()
    this.componetDestroyed.unsubscribe()
  }
}

在某些情况下,我会覆盖 ngOnDestroy 而忘记调用 super.ngOnDestroy(),然后订阅就会变得疯狂。 我向扩展组件添加了一个单元测试以测试取消订阅已被调用,但为此我必须真正记住添加它们。

我的问题是,

如有任何帮助,我们将不胜感激。

  1. 不,没有这种从抽象中自动调用方法的方法。

  2. 您只需要单独进行单元测试。只需创建一个内联测试 class 来扩展您的摘要,然后进行单元测试 ngOnDestroy。完全够了。

我只能想到一种方法,非常粗糙和丑陋。 is 强制执行的一件事是 TypeScript 本身在构造函数中的 super() 调用。因此你可以

class Foo {
  constructor() {
    const oldNgOnDestroy = this.ngOnDestroy;

    this.ngOnDestroy = function() {
      console.log("decorated ngOnDestroy");
      return oldNgOnDestroy();
    }.bind(this);
  }

  ngOnDestroy() {
    console.log("original ngOnDestroy");
  }
}

class Bar extends Foo {
  constructor() {
    super();
  }
}

class Baz extends Foo {
  constructor() {
    super();
  }

  ngOnDestroy() {
    console.log("custom ngOnDestroy");
  }
}

const bar = new Bar();
bar.ngOnDestroy();
const baz = new Baz();
baz.ngOnDestroy();

正如我所说,又黑又丑。

我认为最好的方法是将 "noImplicitOverride": true 添加到您的 tsconfig。它不一定会帮助您记住调用超级方法,但它会强制您明确覆盖方法,在不使用 override 关键字覆盖方法的情况下抛出编译错误。然后由开发人员决定是否需要调用 super 方法。

https://www.typescriptlang.org/tsconfig#noImplicitOverride