在 TypeScript (Angular 2+) 中扩展 EventTarget?

Sla*_* II 5 dom typescript es6-class angular

有没有办法实际创建一个类,它将扩展EventTarget DOM API 类?

考虑一下,我正在上这门课:

class MyClass extends EventTarget {        

  constructor() {
    super();
  }

  private triggerEvent() {
    this.dispatchEvent(new Event('someEvent'));
  }

}
Run Code Online (Sandbox Code Playgroud)

当我尝试实例化它时,我收到此错误:

  • ERROR TypeError: Failed to construct 'EventTarget': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

看起来这是因为这个 API 需要适当的 ES2015 类才能工作,但我正在将我的代码转换为 ES5 级别。

如果我使用这样的构造函数:

constructor() {
  Reflect.construct(EventTarget, [], MyClass);
}
Run Code Online (Sandbox Code Playgroud)

尝试addEventListener()在实例上调用时出现以下错误:

  • ERROR TypeError: Illegal invocation.

作为副作用,我也收到了这个 TypeScript 编译错误:

  • error TS2377: Constructors for derived classes must contain a 'super' call..

Sla*_* II 6

最简单的解决方案是实际实现EventTarget接口,但将实际实现委托给某些现有类,例如DocumentFragment.

此外,我们可以将此功能提取到可重用类中:

export class DelegatedEventTarget implements EventTarget {

  private delegate = document.createDocumentFragment();


  addEventListener(...args: any): void {
    this.delegate.addEventListener.apply(this.delegate, args);
  }

  dispatchEvent(...args: any): boolean {
    return this.delegate.dispatchEvent.apply(this.delegate, args);
  }

  removeEventListener(...args: any): void {
    return this.delegate.removeEventListener.apply(this.delegate, args);
  }

}
Run Code Online (Sandbox Code Playgroud)

然后,我们可以将它用作初始类的父类:

class MyClass extends DelegatedEventTarget {

  private triggerEvent() {
    this.dispatchEvent(new Event('someEvent'));
  }

}
Run Code Online (Sandbox Code Playgroud)

这将保留类型并在编译至 ES5 时继续存在。