-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extending EventEmitter and implementing TypedEmitter results in incompatible eventNames type #3
Comments
Hey @jgornick, thanks for reporting! I have had a look at it, but unfortunately I wasn't able to find a solution yet. If someone else has an idea... The sample code looks something like this: import EventEmitter from "events"
import TypedEventEmitter from "typed-emitter"
interface FooEvents {
bar(text: string): void
}
export default class FooEmitter extends EventEmitter implements TypedEventEmitter<FooEvents> {} |
To get around the issue for now, I created a delegation class that's typed properly: import { EventEmitter as CoreEventEmitter } from 'events'
import TypedEmitter from 'typed-emitter'
type Arguments<T> = [T] extends [(...args: infer U) => any]
? U
: [T] extends [void] ? [] : [T]
export class EventEmitter<Events> implements TypedEmitter<Events> {
public eventEmitter = new CoreEventEmitter() as unknown as TypedEmitter<Events>
public addListener<E extends keyof Events> (event: E, listener: Events[E]): this {
this.eventEmitter.addListener(event, listener)
return this
}
public on<E extends keyof Events> (event: E, listener: Events[E]): this {
this.eventEmitter.on(event, listener)
return this
}
public once<E extends keyof Events> (event: E, listener: Events[E]): this {
this.eventEmitter.once(event, listener)
return this
}
public prependListener<E extends keyof Events> (event: E, listener: Events[E]): this {
this.eventEmitter.prependListener(event, listener)
return this
}
public prependOnceListener<E extends keyof Events> (event: E, listener: Events[E]): this {
this.eventEmitter.prependOnceListener(event, listener)
return this
}
public off<E extends keyof Events>(event: E, listener: Events[E]): this {
this.eventEmitter.off(event, listener)
return this
}
public removeAllListeners<E extends keyof Events> (event: E): this {
this.eventEmitter.removeAllListeners(event)
return this
}
public removeListener<E extends keyof Events> (event: E, listener: Events[E]): this {
this.eventEmitter.removeListener(event, listener)
return this
}
public emit<E extends keyof Events> (event: E, ...args: Arguments<Events[E]>): boolean {
return this.eventEmitter.emit(event, ...args)
}
public eventNames (): (keyof Events)[] {
return this.eventEmitter.eventNames() as (keyof Events)[]
}
public listeners<E extends keyof Events> (event: E): Function[] {
return this.eventEmitter.listeners(event)
}
public listenerCount<E extends keyof Events> (event: E): number {
return this.eventEmitter.listenerCount(event)
}
public getMaxListeners (): number {
return this.eventEmitter.getMaxListeners()
}
public setMaxListeners (maxListeners: number): this {
this.eventEmitter.setMaxListeners(maxListeners)
return this
}
} |
The strict-event-emitter-types package solves the extending EventEmitter problem with this: class MyEventEmitter extends (EventEmitter as { new(): MyEmitter }) {
} Would it help here? |
That looks like a pretty nifty solution. Thanks for sharing, @yoursunny! Will check it out. |
So I tried that trick, but it doesn't work for this use case that way. I propose to solve this issue for now by changing the - eventNames (): (keyof Events)[]
+ eventNames (): (keyof Events | string | symbol)[] Pro:
Con:
|
Sacrifice a little bit of type safety in order to be able to do `class MyEmitter extends EventEmitter implements TypedEventEmitter<MyEvents>`. Fixes #3.
Sacrifice a little bit of type safety in order to be able to do `class MyEmitter extends EventEmitter implements TypedEventEmitter<MyEvents>`. Fixes #3.
Fix published as v1.1.0 🚀 |
For example:
Results in error:
Workaround is to implement
eventNames
and override typing:The text was updated successfully, but these errors were encountered: