I'm working on a WSS server using the Node ws library. Specifically, using the approach described in this question which may or may not be relevant.
I built a prototype server that works perfectly, but when I try to bring the same code across to my regular project, it doesn't work.
I wanted an easy way to identify the origin server for any websocket request:
import { Server, Data, WebSocket } from "ws";
interface IIdWebSocket extends WebSocket {
id: string;
}
export class WSSServer {
private wss = new Server<IIdWebSocket>({ port: 8090 });
// and so on
Now the problem I have is that when I try to build this in my real project, I get the following message in the new Server<IIdWebSocket>
line:
src/wws-server.ts:24:30 - error TS2344: Type 'IIdWebSocket' does not satisfy the constraint 'typeof WebSocket'.
Type 'IIdWebSocket' is missing the following properties from type 'typeof WebSocket': prototype, createWebSocketStream, Server, WebSocketServer, and 9 more
I can't see an obvious difference between the version of the code that works and the version that doesn't. I notice that looking at the definitely typed source for the typescript library the property it is complaining about isn't a property of WebSocket
at all - instead it appears to be a property of the Server type.
What is happening here?
It's expecting the type of a class constructor and you are passing it an object type. The value WebSocket
is a class constructor, and so typeof WebSocket
is the type for that constructor.
type IIdWebSocketConstructor = typeof WebSocket & {
new(): IIdWebSocket
}
interface IIdWebSocket extends WebSocket {
id: string
}
This creates a constructor type that returns IIdWebSocket
when constructed.
export class WSSServer {
private wss = new Server<IIdWebSocketConstructor>({ port: 8090 });
testing123() {
this.wss.on('connection', (socket) => {
socket.id // works
// ^? number
})
}
}