Skip to content

Commit

Permalink
fix(typings): add fallback to untyped event listener (#3834)
Browse files Browse the repository at this point in the history
Related: #3833
  • Loading branch information
MaximeKjaer authored Mar 31, 2021
1 parent 259f297 commit a11152f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
22 changes: 17 additions & 5 deletions lib/typed-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 32 additions & 0 deletions test/socket.io.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down

0 comments on commit a11152f

Please sign in to comment.