I use various Capacitor plugins in my Angular app. They basically consists on methods, and also listeners. Here comes an example from Keyboard plugin : addListener(eventName: 'keyboardWillShow', listenerFunc: (info: KeyboardInfo) => void): Promise<PluginListenerHandle> & PluginListenerHandle; addListener(eventName: 'keyboardDidShow', listenerFunc: (info: KeyboardInfo) => void): Promise<PluginListenerHandle> & PluginListenerHandle; addListener(eventName: 'keyboardWillHide', listenerFunc: () => void): Promise<PluginListenerHandle> & PluginListenerHandle; addListener(eventName: 'keyboardDidHide', listenerFunc: () => void): Promise<PluginListenerHandle> & PluginListenerHandle; I created a method that calls these addListener methods, but I don't know how to type it to achieve what I want : myMethod(Keyboard, 'keyboardWillShow') // return type : Observable<KeyboardInfo> myMethod(Keyboard, 'keyboardWillHide') // return type : Observable<void> myMethod(Keyboard, 'nonexisting') // TS Error I want to type my method in a way that it accepts plugin in first argument, and only accepts in second arg event names for which an addListener overload exists and accept it as its first arg. I also want, if possible, to infer the type of the callback argument according to the event name. For now, I have no idea of how to achieve this. type CapacitorPlugin = { addListener: (eventName: any, listener: (event: any) => void) => Promise<PluginListenerHandle> & PluginListenerHandle } ... export function fromCapacitorListener(plugin: CapacitorPlugin, eventName: unknown): Observable<any> { /* ... */ } Continue reading...