具有预定义类型提取功能参数的动态类型



我想知道是否可以创建一个动态类型来替换两个参数,比如在on: (eventName: EventName, callback: (data: any) => void) => void中,用更接近这个on: (DynamicParams<EventName>) => void的东西,这样它就可以从预定义的集合中提取callback's类型,并使用它来代替any类型。

我认为用一些代码来解释会更容易。

比如说,我有一组不同类型的事件:

const events = ['loaded', 'changed'];
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType[number];
type EventName = ArrayElement<typeof events>

以及仅当已经发出特定通知时才运行的功能;

const on = (eventName: EventName, callback: (data: any) => void) => {}

但我希望能够将此函数与接受不同参数类型的回调一起使用,而无需手动检查类型,也无需任何强制转换,例如:

on('loaded', (list: Entry[]) => {
// do something with loaded array of elements;
}
on('changed', (index: number) => {
// do something with index of a changed entry;
}

有没有一种方法可以创建一个接受EventName并向给定事件返回特定类型的映射类型?

类似的东西:

const on(eventName: EventName, DynamicMethod<'eventName'> => void) => {}
const on(DynamicParams<'eventName'>) => {}

假设,我需要替换事件对象并在其位置创建一个类型,而不是:

type events = [
{
name: 'loaded',
method: (list: Entry[]) => void
},
{
name: 'changed',
method: (index: number) => void
}
]

但我不知道如何提取名称值(而不是值的类型(。

如果您定义了事件名称到其数据类型的映射:

type EventMap = {
loaded: Entry[];
changed: number;
};

您可以使on通用:

const on = <E extends EventName>(eventName: E, callback: (data: EventMap[E]) => void) => {}
on('loaded', (list) => {
//            ^? Entry[]
});
on('changed', (index) => {
//             ^? number
});

游乐场

有两种方法可以实现这一点:

使用呼叫签名:

interface OnEvent {
(eventName: 'loaded', callback: (list: Entry[]) => void): void;
(eventName: 'changed', callback: (index: number) => void): void;
}
const on: OnEvent = (eventName, callback) => {
// Choose how to register the event here...
}

或功能过载:

function on(eventName: 'loaded', callback: (list: Entry[]) => void): void;
function on(eventName: 'changed', callback: (index: number) => void): void;
function on(eventName: string, callback: (data: any) => void) {
// Choose how to register the event here...
}

最新更新