// Map all your event names with their handlers
type CustomEmitterEvents = {
eventA: (payload: number) => void
eventB: (payload: string) => void
eventC: (arg: boolean, msg: string) => void
}
// Interface of your sublcass, matches the EventEmitter method signatures
interface CustomEmitter {
// Matches EventEmitter.on
on<T extends keyof CustomEmitterEvents>(event: T, listener: CustomEmitterEvents[T]): this
// Matches EventEmitter.off
off<T extends keyof CustomEmitterEvents>(event: T, listener: CustomEmitterEvents[T]): this
// Matches EventEmitter.emit
emit<T extends keyof CustomEmitterEvents>(event: T, ...args: Parameter<CustomEmitterEvents[T]>: boolean
}
// Define your subclass
class SuperEmitter extends EventEmitter implements CustomEmitter {
// Override parent class on method
override on<T extends keyof CustomEmitterEvents>(event: T, listener: CustomEmitterEvents[T]): this {
super.on(event, listener)
return this
}
// other stuff...
}
// You can use it like below
const emitter = new SuperEmitter()
emitter.on('eventA', (payload: number) => {
// your stuff...
})
emitter.on('eventC', (arg: boolean, msg: string) => {
// your stuff...
})THX to BRIAN MANCINI for his idea.