This is really neat. I've been doing something similar but way less elegant — basically just a plain object with event name keys mapping to callback arrays, which obviously gives you zero type safety.
The dispatchEvent overload with the conditional tuple type for void events is a nice touch. I always end up with awkward undefined params when an event doesn't carry data.
One thing I'm wondering — have you run into issues with memory leaks when listeners aren't properly cleaned up? With the native EventTarget you don't get a once equivalent on removeEventListener, so I've had to be pretty disciplined about cleanup in SPAs. Do you add any kind of dispose pattern on top of this?
For removing event listeners you can either use the native once, this will disconnect the event listener once it's been caught once.
// set the event listener to onceshoppingCartSingleton.addEventListener('item-added',(event)=>{...},{once:true});
Or, my preferred method, you can send an abort signal to remove as many event listeners as you like.
// declare an abort controllerconstac=newAbortController();// pass the signal through to the event listenershoppingCartSingleton.addEventListener('item-added',(event)=>{...},{signal:ac.signal});// abort the AbortController to remove the event listenerac.abort();
For example in react you would do something like this
useEffect(()=>{constac=newAbortController();// attach 3 listeners all with the same signalshoppingCartSingleton.addEventListener('item-added',(event)=>{...},{signal:ac.signal});shoppingCartSingleton.addEventListener('item-removed',(event)=>{...},{signal:ac.signal});shoppingCartSingleton.addEventListener('cart-cleared',(event)=>{...},{signal:ac.signal});// on unmount, all 3 listeners are removed.return ()=>ac.abort();},[])
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
This is really neat. I've been doing something similar but way less elegant — basically just a plain object with event name keys mapping to callback arrays, which obviously gives you zero type safety.
The
dispatchEventoverload with the conditional tuple type for void events is a nice touch. I always end up with awkwardundefinedparams when an event doesn't carry data.One thing I'm wondering — have you run into issues with memory leaks when listeners aren't properly cleaned up? With the native EventTarget you don't get a
onceequivalent on removeEventListener, so I've had to be pretty disciplined about cleanup in SPAs. Do you add any kind ofdisposepattern on top of this?For removing event listeners you can either use the native
once, this will disconnect the event listener once it's been caught once.Or, my preferred method, you can send an abort signal to remove as many event listeners as you like.
For example in react you would do something like this