andywer / andywer/typed-emitter

[QUESTION] How can I use in an abstract class that extends `EventEmitter`?

未关闭
#30 5 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
question
主要语言
JavaScript
星标
285
派生
29
PR 合并指标
30 天内没有已合并 PR

描述

Thank you for the package! I'm struggling to achieve something that I'm sure is an easy task for some. Is this possible?

How can I extend an abstract `EventEmitter` class, with common events?

**Example:**

```typescript
import EventEmitter from "events";
import TypedEmitter from "typed-emitter";

type BaseEvents = {
BASE_EVENT: (arg: string) => void;
};

abstract class BaseEmitter extends (EventEmitter as {
new (): TypedEmitter;
}) {
constructor() {
super();
// How can I make this type safe ????
this.emit("BASE_EVENT", "string-value"); // <-- How can I achieve type safety here
}
}

type ImpOneEvents = {
C1_EVENT: (a: number) => void;
};
class ImpOne extends BaseEmitter {
constructor() {
super();
this.emit("C1_EVENT", 1); // OK: type checks ok (GOOD)
this.emit("C1_EVENT", "bla"); // ERROR: string not assignable (GOOD)
}
}

type ImpTwoEvents = {
C2_EVENT: (a: boolean) => void;
};
class ImpTwo extends BaseEmitter {
constructor() {
super();
this.emit("C2_EVENT", true); // OK: type checks ok (GOOD)
}
}

const impTwo = new ImpTwo();
impTwo.on("C2_EVENT", (a) => {
parseFloat(a); // ERROR: Type of boolean not assignable to parameter of type string (GOOD)
});
```

I've tried

```typescript
type BaseEvents = {
BASE_EVENT: (arg: string) => void;
};

abstract class BaseEmitter extends (EventEmitter as {
new (): TypedEmitter;
}) {
...
```
And lots of other things. The above results in

`Argument of type '[string]' is not assignable to parameter of type 'Arguments<(T & BaseEvents)["BASE_EVENT"]>'.`

For line

```typescript
this.emit("BASE_EVENT", "string-value"); // <-- How can I achieve type safety here
```

贡献指南

这个仓库没有索引到贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。