简体   繁体   English

编译到 ES5 时在 TypeScript (Angular 2+) 中扩展 EventTarget

[英]Extending EventTarget in TypeScript (Angular 2+) when compiling to ES5

Is there a way to actually create a class, which will extend the EventTarget DOM API class?有没有办法实际创建一个类,它将扩展EventTarget DOM API 类?

Consider, I'm having this class:考虑一下,我正在上这门课:

class MyClass extends EventTarget {        

  constructor() {
    super();
  }

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

}

When I'm trying to instantiate it, I'm getting this error:当我试图实例化它时,我收到了这个错误:

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

Looks like this is due to the fact, that this API requires proper ES2015 classes in order to work, but I'm transpiling my code down to ES5 level.看起来这是因为这个 API 需要适当的 ES2015 类才能工作,但我正在将我的代码转换为 ES5 级别。

If I use a constructor like this:如果我使用这样的构造函数:

constructor() {
  Reflect.construct(EventTarget, [], MyClass);
}

I'm getting the following error, when trying to invoke addEventListener() on the instance:尝试在实例上调用addEventListener()时出现以下错误:

  • ERROR TypeError: Illegal invocation . ERROR TypeError: Illegal invocation

As a side effect, I'm also getting this TypeScript compilation error:作为副作用,我也收到了这个 TypeScript 编译错误:

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

The most simple solution would be to actually implement the EventTarget interface, but to delegate the actual implementation to some existing class, like DocumentFragment .最简单的解决方案是实际实现EventTarget接口,但将实际实现委托给某个现有类,例如DocumentFragment

Also, we could extract this functionality to the reusable class:此外,我们可以将此功能提取到可重用类中:

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

}

Then, we can use it as a parent for our initial class:然后,我们可以将它用作我们初始类的父类:

class MyClass extends DelegatedEventTarget {

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

}

This will preserve the typings and will survive the compilation down to ES5.这将保留类型,并将在编译到 ES5 时继续存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM