andywer / andywer/typed-emitter

Consider exporting a class

Open
#36 0 comments 3 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
285
Forks
29
PR merge metrics
No merged PRs in 30d

Description

I had struggled with this a few times... The cast to the interface is fine when you just want an emitter, but I had issues extending `EventEmitter`. #30 gets to the root of it. There's really not a way to have an abstract emitter such as:

```ts
import EventEmitter from 'node:events'
import TypedEmitter, { EventMap } from 'typed-emitter'

// Base class expressions cannot reference class type parameters. ts(2562)
// V
class BaseEmitter extends (EventEmitter as new () => TypedEmitter) {
// ...
}
```

I did ultimately find a really ugly way to get a class definition that could be extended as normal:
```ts
import NodeEventEmitter from 'node:events'
import TypedEventEmitter from 'typed-emitter'

const EventEmitter = NodeEventEmitter as unknown as {
new (): TypedEventEmitter extends infer O
? { [K in keyof O]: O[K] }
: never
}

export default class TypedEmitter<
Events extends EventMap,
> extends EventEmitter {}
```

I think the library could export a class without making things very complicated, though. Have a look at the linked PR and see what you think.

The only thing I can see as being a problem is if there is some use for this outside of node. Even then, you could likely have the original as a separate definition and leverage the `exports` field to accommodate that like:
```json
"exports": {
".": {
"node": {
"require": "./index.cjs",
"import": "./index.mjs",
"types": "./index.d.ts"
},
"default": {
"type": "./interface-only.d.ts"
}
},
"./rxjs": {
"node": {
"require": "./rxjs/index.cjs",
"import": "./rxjs/index.mjs",
"types": "./rxjs/index.d.ts"
},
"default": {
"type": "./interface-only.d.ts"
}
}
},
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.