import type { Subscription } from './observable' /** * Type helper to extract event types that have "void" data. This allows to call `notify` without a * second argument. Ex: * * ``` * interface EventMap { * foo: void * } * const LifeCycle = AbstractLifeCycle * new LifeCycle().notify('foo') * ``` */ type EventTypesWithoutData = { [K in keyof EventMap]: EventMap[K] extends void ? K : never }[keyof EventMap] // eslint-disable-next-line no-restricted-syntax export class AbstractLifeCycle { private callbacks: { [key in keyof EventMap]?: Array<(data: any) => void> } = {} notify>(eventType: EventType): void notify(eventType: EventType, data: EventMap[EventType]): void notify(eventType: keyof EventMap, data?: unknown) { const eventCallbacks = this.callbacks[eventType] if (eventCallbacks) { eventCallbacks.forEach((callback) => callback(data)) } } subscribe( eventType: EventType, callback: (data: EventMap[EventType]) => void ): Subscription { if (!this.callbacks[eventType]) { this.callbacks[eventType] = [] } this.callbacks[eventType]!.push(callback) return { unsubscribe: () => { this.callbacks[eventType] = this.callbacks[eventType]!.filter((other) => callback !== other) }, } } }