【发布时间】:2018-11-01 12:34:33
【问题描述】:
我目前有一个带有重载函数的接口,如下所示:
export interface IEvents {
method(): boolean;
on(name: 'eventName1', listener: (obj: SomeType) => void): void;
on(name: 'eventName2', listener: (obj: SomeType) => void): void;
on(name: 'eventName3', listener: (obj: SomeType) => void): void;
on(name: 'eventName4', listener: (obj: SomeType) => void): void;
on(name: 'eventName5', listener: (obj: SomeType) => void): void;
on(name: 'eventName6', listener: () => void): void;
on(name: 'eventName7', listener: (obj: SomeType) => void): void;
on(name: 'eventName8', listener: (obj: SomeType) => void): void;
}
我正在尝试获取联合类型的事件名称,如下所示:
事件名称1 |事件名称2 | ...
我尝试了以下方法,但是当我推断类型时,它似乎只选择了一个名称值,而不是所有这些值的并集。
export type TEventExtension<T extends IEvents> {
[K in keyof T]: K extends 'on' ? TEventListenerName<T[K]> : never;
}[keyof T];
export type TEventListenerName<T> = T extends (name: infer N, listener: (obj?: infer E) => void) => void ? N : never;
const ext: TEventExtension<IEvents> = void 0 as any; // Type: 'eventName8'
我也尝试过使用累加器类型来跟踪联合,但 Typescript 不允许递归泛型。
关于如何实现这一点的任何想法?
编辑:具有重载定义的接口存在于外部模块中。我试图避免 c+ping 从外部定义到我的定义,而是让它自动构建类型。
【问题讨论】:
-
on(name: "eventName1" | "eventName2", listener:() =>void) -
不确定是否可以将
on的重载转换为联合类型(想不出办法,也许其他人有想法)。一种解决方法可能是这里介绍的方法stackoverflow.com/questions/50369299/… -
@JonasW。这不是我想要完成的。我可以轻松地对接口中的事件名称进行硬编码,但我正在尝试创建一种类型,该类型采用模块定义的外部接口并返回可能的事件名称的联合。
标签: javascript typescript typescript-typings