export class Subscribable { protected listeners = new Set() constructor() { this.subscribe = this.subscribe.bind(this) } subscribe(listener: TListener): () => void { this.listeners.add(listener) this.onSubscribe() return () => { this.listeners.delete(listener) this.onUnsubscribe() } } hasListeners(): boolean { return this.listeners.size > 0 } protected onSubscribe(): void { // Do nothing } protected onUnsubscribe(): void { // Do nothing } }