fix(typings): add fallback to untyped event listener (#3834)

Related: https://github.com/socketio/socket.io/issues/3833
This commit is contained in:
Maxime Kjaer
2021-03-31 11:37:37 +02:00
committed by GitHub
parent 259f29720b
commit a11152f42b
2 changed files with 49 additions and 5 deletions

View File

@@ -43,11 +43,23 @@ export type ReservedOrUserListener<
ReservedEvents extends EventsMap,
UserEvents extends EventsMap,
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>
> = Ev extends EventNames<ReservedEvents>
? ReservedEvents[Ev]
: Ev extends EventNames<UserEvents>
? UserEvents[Ev]
: never;
> = FallbackToUntypedListener<
Ev extends EventNames<ReservedEvents>
? ReservedEvents[Ev]
: Ev extends EventNames<UserEvents>
? UserEvents[Ev]
: never
>;
/**
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
*
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
*/
type FallbackToUntypedListener<T> = [T] extends [never]
? (...args: any[]) => void
: T;
/**
* Interface for classes that aren't `EventEmitter`s, but still expose a

View File

@@ -44,6 +44,38 @@ describe("server", () => {
});
});
});
it("infers 'any' for listener parameters of other events using enums", () => {
const srv = createServer();
const sio = new Server(srv);
srv.listen(() => {
sio.on("connection", (socket) => {
expectType<Socket<DefaultEventsMap, DefaultEventsMap>>(socket);
});
enum Events {
CONNECTION = "connection",
TEST = "test",
}
sio.on(Events.CONNECTION, (socket) => {
// TODO(#3833): Make this expect `Socket<DefaultEventsMap, DefaultEventsMap>`
expectType<any>(socket);
socket.on("test", (a, b, c) => {
expectType<any>(a);
expectType<any>(b);
expectType<any>(c);
});
socket.on(Events.TEST, (a, b, c) => {
expectType<any>(a);
expectType<any>(b);
expectType<any>(c);
});
});
});
});
});
describe("emit", () => {