Skip to content

Instantly share code, notes, and snippets.

@barfi
Last active July 26, 2023 17:12
Show Gist options
  • Save barfi/a173f70604b1b95ed75fa0ea52c5cf19 to your computer and use it in GitHub Desktop.
Save barfi/a173f70604b1b95ed75fa0ea52c5cf19 to your computer and use it in GitHub Desktop.
Typed eventemitter subclass
// 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment