Skip to content

Instantly share code, notes, and snippets.

@frzi
Last active August 23, 2025 11:59
Show Gist options
  • Save frzi/9308c4bea6e3e09545150caa99fc7d6b to your computer and use it in GitHub Desktop.
Save frzi/9308c4bea6e3e09545150caa99fc7d6b to your computer and use it in GitHub Desktop.
Typed EventTarget for TypeScript
export default class TypedEventTarget<Events extends object> extends EventTarget {
override addEventListener<K extends keyof Events, U = Events[K] extends Event ? Events[K] : CustomEvent<Events[K]>>(
type: K,
listener: (this: this, event: U) => void,
options?: AddEventListenerOptions | boolean
) {
super.addEventListener(type as string, listener as any, options)
}
override dispatchEvent<K extends keyof Events>(type: K, detail: Events[K]): boolean
override dispatchEvent<K extends keyof Events>(event: Event): boolean
override dispatchEvent<K extends keyof Events>(type: K | Event, detail?: Events[K]): boolean {
const event = type instanceof Event ? type : new CustomEvent(type as string, { detail })
const prop = this['on' + event.type] as (event: Event) => void
prop?.call(this, event)
return super.dispatchEvent(event)
}
override removeEventListener<K extends keyof Events, U = Events[K] extends Event ? Events[K] : CustomEvent<Events[K]>>(
type: K,
listener: (this: this, event: U) => void,
options?: AddEventListenerOptions | boolean
) {
super.removeEventListener(type as string, listener as any, options)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment