andywer / andywer/typed-emitter

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

オープン
#30 コメント 5 件 リアクション 0 件 担当者 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 を短くまとめたダイジェスト。