I currently have an interface with overloaded functions like so:
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;
}
I am trying to get the union type of event names like so:
eventName1 | eventName2 | ...
I have tried the following, but when I infer the type it seems to only pick one of the name values and not a union of all of them.
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'
I have also tried using an accumulator type to keep track of the unions, but Typescript doesnt allow recursive generics.
Any ideas on how I can accomplish this?
Edit: The interface with the overloaded definitions exists in an external module. I am trying to avoid c+ping from the external definitions to my definitions, and instead have it build the type automatically.