TypeScript:EventEmitter子类事件的专用签名 [英] TypeScript: specialized signatures for EventEmitter subclass events

查看:577
本文介绍了TypeScript:EventEmitter子类事件的专用签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a base class EventEmitter, which has the on method to bind handlers on specific events:

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

    protected emit(event: string, ...args) {
        /* call all handlers listening on event */
    }
}

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

Now I have various subclasses, which can emit different events with different arguments. I'd like to "declare" which events can be emitted by that specific class:

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

所以我的子类可能会发出事件event1event2,但这似乎不是正确的指定方法. TypeScript(tsc 1.8)正在更新:

So my sub class may emit the events event1 and event2, but this does not seem to be the right way to specify. TypeScript (tsc 1.8) is compaining:

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.

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

So, what is the intended way to specify the events my class can emit?

我找到了所要查找的名称:

I've found the name of what I was looking for: Specialized Signatures. However, it seems to be meant for interfaces only, and not for new TypeScript code.

现在我找到了其他问题关于2015年的同一问题,但是那里的解决方案看起来不太正确.那么,今天在TypeScript中还有其他方法可以做到这一点吗?

Now I've found anothother question about the same issue from 2015, however the solution there does not look quite right. So, are there other ways to do it in TypeScript today?

推荐答案

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

what is the intended way to specify the events my class can emit?

与其使用包含所有类型的em的单个 event 流,更容易为每个 类型.

Instead of using a single event stream that contains all the types its easier to have a separate event stream for each type.

这是我称为TypedEvent的概念.使用它的一个示例项目是 http://alm.tools/

This is a concept I call TypedEvent. One example project that uses it is 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

Here is an example usage : 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

这篇关于TypeScript:EventEmitter子类事件的专用签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆