在扩展 EventEmitter 的 TypeScript 类中声明事件

新手上路,请多包涵

我有一个类 extends EventEmitter 可以发出事件 hello 。如何声明具有特定事件名称和侦听器签名的 on 方法?

 class MyClass extends events.EventEmitter {

  emitHello(name: string): void {
    this.emit('hello', name);
  }

  // compile error on below line
  on(event: 'hello', listener: (name: string) => void): this;
}

原文由 aleung 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 841
2 个回答

最有用的方法是使用 declare

 declare interface MyClass {
    on(event: 'hello', listener: (name: string) => void): this;
    on(event: string, listener: Function): this;
}

class MyClass extends events.EventEmitter {
    emitHello(name: string): void {
        this.emit('hello', name);
    }
}

请注意,如果要 导出 类, 必须使用 export 关键字声明接口和类。

原文由 SergeyK 发布,翻译遵循 CC BY-SA 4.0 许可协议

扩展@SergeyK 的答案,有了这个,您可以对 emiton 函数进行类型检查和完成,而无需重复事件类型。

  1. 为每种事件类型定义事件侦听器签名:
 interface MyClassEvents {
  'add': (el: string, wasNew: boolean) => void;
  'delete': (changedCount: number) => void;
}

  1. 声明为 MyClass 构造类型的接口,基于 EventListeners ( MyClassEvents ) 函数签名:
 declare interface MyClass {
  on<U extends keyof MyClassEvents>(
    event: U, listener: MyClassEvents[U]
  ): this;

  emit<U extends keyof MyClassEvents>(
    event: U, ...args: Parameters<MyClassEvents[U]>
  ): boolean;
}

  1. 简单地定义你的类扩展 EventEmitter
 class MyClass extends EventEmitter {
  constructor() {
    super();
  }
}


现在您将获得 onemit 函数的类型检查:

在此处输入图像描述

在此处输入图像描述

不幸的是,您只能对这两个函数进行完成和类型检查(除非您在 MyClass 接口中定义更多函数)。

要获得更通用的解决方案,您可以使用 此包注意: 它不会增加运行时开销。

 import { TypedEmitter } from 'tiny-typed-emitter';

interface MyClassEvents {
  'add': (el: string, wasNew: boolean) => void;
  'delete': (changedCount: number) => void;
}

class MyClass extends TypedEmitter<MyClassEvents> {
  constructor() {
    super();
  }
}

原文由 Binier 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题