是否可以声明一个元素依赖于另一个元素的泛型元组?
例如,有了这个限制:
interface Event<T, P extends any[] = []> {
type: T; // event name e.g. 'stop'
payload: P; // event parameters e.g. coordinates
}
type MovementEvents = Event<'stop'>| Event<'run', [number, number]>;
这种实现(不正确(:
type TransitionTuple<E extends Event<any, any>> = [
EventType<E>,
(...args: EventPayloadMap[E]) => void,
];
以某种方式进行转换,以便第二个元素(回调(将取决于第一个元素(类型(:
const transition: TransitionTuple<MovementEvents> = [
'run',
() => {}, // here must be an error, because the callback args don't match the event
];
在开始之前,我将Event
重命名为EventThing
,因为Event
已经是一个东西,可能会给一些人(以及TypeScript本身(带来困惑。
在并集上进行分发,并为每个成员创建一个元组:
type TransitionTuple<U extends EventThing<any, any[]>> = U extends U ? [U["type"], (...args: U["payload"]) => void] : never;
以下所有功能现在都起作用:
const transitions: TransitionTuple<MovementEvents>[] = [
[
'run',
() => {},
],
[
'run',
(a, b) => {},
],
[
'stop',
() => {},
]
];
请注意,对于第一个条目,它是有效的,因为函数不需要使用参数。将其作为一个错误是一种糟糕的开发人员体验,因为开发人员将被迫命名无用的未使用变量。
游乐场