Description
hi and thx for this @MaximeKjaer
#3822
Observation
I wanted to use socketio together with rxjs and found out that the typescript compiler can no longer follow through the type EventEmitter
https://github.com/socketio/socket.io/blame/fd9dd74eeed3fa6a15c63240df30cc3b7357102f/lib/typed-events.ts#L93
https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/fromEvent.ts#L62-L110
example code which i have reduced to the essential(click me)
import { fromEvent } from 'rxjs';
import { EventEmitter } from 'events';
interface EventsMap {
[event: string]: any;
}
declare type EventNames<Map extends EventsMap> = keyof Map & (string | symbol);
// here the event emitter causes problems
class MyTarget<UserEvents extends EventsMap> extends EventEmitter {
// since the eventemitter adds the general event listening ("addListener", "removeListener") methods without strict types
on<Ev extends EventNames<UserEvents>>(ev: Ev, listener: UserEvents[Ev]) {
return this;
}
off<Ev extends EventNames<UserEvents>>(ev: Ev, listener: UserEvents[Ev]) {
return this;
}
}
// socket io event declaration approach - @see https://socket.io/docs/v4/typescript/
interface MyEvents {
foo: (firstParam: boolean) => void;
}
const target = new MyTarget<MyEvents>();
// expect boolean type for the argument
fromEvent(target, 'foo').subscribe((firstParam) => {
console.log('firstParam', firstParam);
});
Problem
Since the eventemitter adds the general event listening ("addListener", "removeListener") methods without strict types, the typescript compiler cannot follow the listener argument types
same also happens with the direct usage of addListener
and removeListener
in example https://socket.io/docs/v4/typescript/#types-for-the-server
socket.addListener('basicEmit', (a, b, c) => {})
Idea
The request would be to get rid of the native EventEmitter and replace it with the methods with a stricter one
so that also the typescript of other libraries can follow and more type support for the other native methods exists