I am trying to have two distinct overloads for event emission: One that maps to custom events, with well-known listener arguments (And thus dispatch time arguments)
export type EngineEvents
= ['window-exit', () => void]
| ['test', (code: number) => void]
| ['pre-init', () => void]
| ['post-init', () => void]
| ['tick-start', () => void]
| ['draw-start', () => void]
;
The problem here is to map those types to the dispatch type, without having to repeat all over again, I've tried the following:
export type EventArgs = [EngineEvents[0], ...Parameters<EngineEvents[1]>];
But that expands to a tuple that contains a union in each cell, which is not what I want. I would like to have the tupple mapped the other way round, for example:
// Instead of
type A = [ 'a' | 'b', 1 | 2 ];
// Have this:
type B = [ 'a', 1 ] | [ 'b', 2 ];
I've tried using the T extends any? whatever : never
idiom as suggested by this answer: TypeScript: Map union type to another union type
But it didn't work out.
export type ArgumentExpand<U> = U extends any[]? [U[0], ...U[1]] : never;
Is there any way of mapping the union, one-by-one so when accessing the first and second element of the tuple it does not mix them up?
Like a map operation, but for the type.