andywer / andywer/typed-emitter
Consider exporting a class
- 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.