I would like the function to know based on the first parameter to know the next parameters and the return type that it will have.
The types I created:
export type EventCallbackMap = {
cancelToken: (cancel: VoidFunction, node: FormKitNode) => void;
before: (visit: PendingVisit, node: FormKitNode) => boolean| void;
start: (visit: PendingVisit, node: FormKitNode) => void;
progress: (progress: Progress, node: FormKitNode) => void;
finish: (visit: ActiveVisit, node: FormKitNode) => void;
cancel: (node: FormKitNode) => void;
success: (page: Page, node: FormKitNode) => Promise<void> | void;
error: (errors: Errors, node: FormKitNode) => Promise<void> | void;
};
export type EventNames = keyof EventCallbackMap;
export type EventCallback<TEventName extends EventNames> =
(...params: Parameters<EventCallbackMap[TEventName]>) => ReturnType<EventCallbackMap[TEventName]>;
export type EventMap<TEventName extends EventNames> = Map<TEventName, Set<EventCallback<EventNames>>>;
export type EventOnFunction = <TEventName extends EventNames>(eventName: TEventName, callback: EventCallback<TEventName>) => void;
export type EventRunFunction = <TEventName extends EventNames>(eventName: TEventName, ...params: Parameters<EventCallbackMap[TEventName]>) => ReturnType<EventCallbackMap[TEventName]>;
export type AddonCallback = (on: EventOnFunction) => void;
export type AddonSet = Set<AddonCallback>;
And the function:
const runEvents: EventRunFunction = (eventName, ...params) => {
const _eventSet = eventList.get(eventName);
if (!_eventSet) return;
for (const event of _eventSet as Set<EventCallbackMap[typeof eventName]>) {
const args = params as Parameters<EventCallbackMap[typeof eventName]>;
const res = event(...args);
if (!res) return res;
}
};