打字稿模板文字类型 - 结合

时间:2021-07-06 13:49:24

标签: typescript

假设我们有活动列表:

type Events = ['error', 'config', 'ready']

我为事件处理程序创建了类型

 on(event: 'error', listener: Listener);
 on(event: 'config', listener: Listener);
 on(event: 'ready', listener: Listener);

我正在努力为这样的东西创建类型:

api.on('error config', (data: any) => any) or
api.on('config error ready', (data: any) => any) etc 

我们可以用模板文字在 TS 中使用递归语法以某种方式做到这一点吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

您应该能够使用函数重载、泛型和实用程序类型来实现这一点:

type APIEvent = 'error' | 'config' | 'ready';

type APIEventHandler = {
    // This signature allows only one event type, from the `APIEvent` union type.
    (event: APIEvent, listener: () => void): void;

    // This signature allows two event types, the first one of type `APIEvent` and the second one `APIEvent` minus whatever the first one is.
    <TEvent extends APIEvent, TEvent2 extends Exclude<APIEvent, TEvent>>(event: `${TEvent} ${TEvent2}`, listener: () => void): void;

    // This signature allows three event types, the first one of type `APIEvent`, the second one `APIEvent` minus whatever the first one is and the third one `APIEvent` minus the first and second parameters.
    <TEvent extends APIEvent, TEvent2 extends Exclude<APIEvent, TEvent>, TEvent3 extends Exclude<APIEvent, TEvent2>>(event: `${TEvent} ${TEvent2} ${TEvent3}`, listener: () => void): void;
}

// Here you would implement the actual behaviour
declare const handler: APIEventHandler;

// These work
handler('error', () => {});
handler('error config', () => {});
handler('error config ready', () => {});

// These do not compile
handler('test', () => {});
handler('error error', () => {});
handler('error config ready ready', () => {});

查看 TypeScript 游乐场 here