映射联合元组类型,保留分布
Mapping union tuple types, preserving the distribution
我正在尝试为事件发射设置两个不同的重载:一个映射到自定义事件,具有众所周知的侦听器参数(因此调度时间参数)
export type EngineEvents
= ['window-exit', () => void]
| ['test', (code: number) => void]
| ['pre-init', () => void]
| ['post-init', () => void]
| ['tick-start', () => void]
| ['draw-start', () => void]
;
这里的问题是将这些类型映射到调度类型,而不必从头再来,我尝试了以下方法:
export type EventArgs = [EngineEvents[0], ...Parameters<EngineEvents[1]>];
但这会扩展为在每个单元格中包含联合的元组,这不是我想要的。我想以相反的方式映射元组,例如:
// Instead of
type A = [ 'a' | 'b', 1 | 2 ];
// Have this:
type B = [ 'a', 1 ] | [ 'b', 2 ];
我试过使用这个答案建议的 T extends any? whatever : never
习语:
但是没有成功。
export type ArgumentExpand<U> = U extends any[]? [U[0], ...U[1]] : never;
是否有任何方法可以逐个映射并集,以便在访问元组的第一个和第二个元素时不会混淆它们?
类似于映射操作,但针对的是类型。
Distributive conditional type 将在此处完成工作:
type MapArgs<E> = E extends [string, (...args: any[]) => any]
? [E[0], ...Parameters<E[1]>] : never;
type EventArgs = MapArgs<EngineEvents>;
我正在尝试为事件发射设置两个不同的重载:一个映射到自定义事件,具有众所周知的侦听器参数(因此调度时间参数)
export type EngineEvents
= ['window-exit', () => void]
| ['test', (code: number) => void]
| ['pre-init', () => void]
| ['post-init', () => void]
| ['tick-start', () => void]
| ['draw-start', () => void]
;
这里的问题是将这些类型映射到调度类型,而不必从头再来,我尝试了以下方法:
export type EventArgs = [EngineEvents[0], ...Parameters<EngineEvents[1]>];
但这会扩展为在每个单元格中包含联合的元组,这不是我想要的。我想以相反的方式映射元组,例如:
// Instead of
type A = [ 'a' | 'b', 1 | 2 ];
// Have this:
type B = [ 'a', 1 ] | [ 'b', 2 ];
我试过使用这个答案建议的 T extends any? whatever : never
习语:
但是没有成功。
export type ArgumentExpand<U> = U extends any[]? [U[0], ...U[1]] : never;
是否有任何方法可以逐个映射并集,以便在访问元组的第一个和第二个元素时不会混淆它们?
类似于映射操作,但针对的是类型。
Distributive conditional type 将在此处完成工作:
type MapArgs<E> = E extends [string, (...args: any[]) => any]
? [E[0], ...Parameters<E[1]>] : never;
type EventArgs = MapArgs<EngineEvents>;