Skip to content

Commit 8d07018

Browse files
authored
fix(typings): add fallback to untyped event listener (socketio#3834)
Related: socketio#3833
1 parent 00c661e commit 8d07018

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

lib/typed-events.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,23 @@ export type ReservedOrUserListener<
4343
ReservedEvents extends EventsMap,
4444
UserEvents extends EventsMap,
4545
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>
46-
> = Ev extends EventNames<ReservedEvents>
47-
? ReservedEvents[Ev]
48-
: Ev extends EventNames<UserEvents>
49-
? UserEvents[Ev]
50-
: never;
46+
> = FallbackToUntypedListener<
47+
Ev extends EventNames<ReservedEvents>
48+
? ReservedEvents[Ev]
49+
: Ev extends EventNames<UserEvents>
50+
? UserEvents[Ev]
51+
: never
52+
>;
53+
54+
/**
55+
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
56+
*
57+
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
58+
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
59+
*/
60+
type FallbackToUntypedListener<T> = [T] extends [never]
61+
? (...args: any[]) => void
62+
: T;
5163

5264
/**
5365
* Interface for classes that aren't `EventEmitter`s, but still expose a

test/socket.io.test-d.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,38 @@ describe("server", () => {
4444
});
4545
});
4646
});
47+
48+
it("infers 'any' for listener parameters of other events using enums", () => {
49+
const srv = createServer();
50+
const sio = new Server(srv);
51+
srv.listen(() => {
52+
sio.on("connection", (socket) => {
53+
expectType<Socket<DefaultEventsMap, DefaultEventsMap>>(socket);
54+
});
55+
56+
enum Events {
57+
CONNECTION = "connection",
58+
TEST = "test",
59+
}
60+
61+
sio.on(Events.CONNECTION, (socket) => {
62+
// TODO(#3833): Make this expect `Socket<DefaultEventsMap, DefaultEventsMap>`
63+
expectType<any>(socket);
64+
65+
socket.on("test", (a, b, c) => {
66+
expectType<any>(a);
67+
expectType<any>(b);
68+
expectType<any>(c);
69+
});
70+
71+
socket.on(Events.TEST, (a, b, c) => {
72+
expectType<any>(a);
73+
expectType<any>(b);
74+
expectType<any>(c);
75+
});
76+
});
77+
});
78+
});
4779
});
4880

4981
describe("emit", () => {

0 commit comments

Comments
 (0)