TypeScript:EventEmitter子类事件的专用签名

Sim*_*mon 8 events overloading typescript typescript1.8

我有一个基类EventEmitter,它具有on绑定特定事件处理程序的方法:

class EventEmitter {
    on(event: string, handler: Function) {
        /* add handler internally */
    }

    protected emit(event: string, ...args) {
        /* call all handlers listening on event */
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我有各种子类,它们可以使用不同的参数发出不同的事件.我想"声明"该特定类可以发出哪些事件:

class MyClass extends EventEmitter {
    on(event: 'event1', handler: (arg1: number) => void): void;
    on(event: 'event2', handler: (arg1: string, arg2: number) => void): void;
}
Run Code Online (Sandbox Code Playgroud)

所以,我的子类可以发出事件event1event2,但是这似乎并没有被指定正确的方式.TypeScript(tsc 1.8)正在补偿:

error TS2415: Class 'MyClass' incorrectly extends base class 'EventEmitter'.
  Types of property 'on' are incompatible.
Type '(event: "event1", handler: (arg1: number) => void) => void' is not assignable to type '(event: string, handler: Function) => void'.
  Type '(event: "event1", handler: (arg1: number) => void) => void' provides no match for the signature '(event: string, handler: Function): void'
error TS2382: Specialized overload signature is not assignable to any non-specialized signature.
error TS2391: Function implementation is missing or not immediately following the declaration.
Run Code Online (Sandbox Code Playgroud)

那么,指定我的类可以发出的事件的预期方式是什么?

编辑:我找到了我要找的名字:Specialized Signatures.但是,它似乎仅适用于接口,而不适用于新的TypeScript代码.

现在我发现anothother问题同一个问题从2015年开始,但有解决方案看起来并不完全正确.那么,今天有没有其他方法可以在TypeScript中实现呢?

bas*_*rat 2

指定我的类可以发出的事件的预期方法是什么?

与使用包含所有类型的单个事件流相比,为每种类型使用单独的事件流更容易。

这就是我所说的一个概念TypedEvent。使用它的一个示例项目是http://alm.tools/

实施: https: //github.com/alm-tools/alm/blob/55a8eb0f8ee411a506572abce92085235658b980/src/common/events.ts#L20-L72

这是一个示例用法:https://github.com/alm-tools/alm/blob/55a8eb0f8ee411a506572abce92085235658b980/src/server/lang/errorsCache.ts#L10

export let errorsUpdated = new TypedEvent<ErrorsUpdate>();
// emit: 
errorsUpdated.emit({} /* this will be type checked */);
// consume:
errorsUpdated.on((x)=>null); // x has the correct inferred type
Run Code Online (Sandbox Code Playgroud)