Skip to main content
Version: 4.x

TypeScript

从 v3 开始,Socket.IO 现在对 TypeScript 具有一流的支持。

¥Starting with v3, Socket.IO now has first class support for TypeScript.

服务器的类型

¥Types for the server

首先声明一些类型:

¥First, declare some types:

interface ServerToClientEvents {
noArg: () => void;
basicEmit: (a: number, b: string, c: Buffer) => void;
withAck: (d: string, callback: (e: number) => void) => void;
}

interface ClientToServerEvents {
hello: () => void;
}

interface InterServerEvents {
ping: () => void;
}

interface SocketData {
name: string;
age: number;
}

并在创建服务器时使用它们:

¥And use them when creating your server:

const io = new Server<
ClientToServerEvents,
ServerToClientEvents,
InterServerEvents,
SocketData
>();

然后,从 IDE 的帮助中获益!

¥Then, profit from the help of your IDE!

发送和广播事件时使用 ServerToClientEvents 接口中声明的事件:

¥The events declared in the ServerToClientEvents interface are used when sending and broadcasting events:

io.on("connection", (socket) => {
socket.emit("noArg");
socket.emit("basicEmit", 1, "2", Buffer.from([3]));
socket.emit("withAck", "4", (e) => {
// e is inferred as number
});

// works when broadcast to all
io.emit("noArg");

// works when broadcasting to a room
io.to("room1").emit("basicEmit", 1, "2", Buffer.from([3]));
});

接收事件时使用 ClientToServerEvents 接口中声明的:

¥The ones declared in the ClientToServerEvents interface are used when receiving events:

io.on("connection", (socket) => {
socket.on("hello", () => {
// ...
});
});

InterServerEvents 接口中声明的用于服务器间通信(在 socket.io@4.1.0 中添加):

¥The ones declared in the InterServerEvents interface are used for inter-server communication (added in socket.io@4.1.0):

io.serverSideEmit("ping");

io.on("ping", () => {
// ...
});

最后,SocketData 类型用于键入 socket.data 属性(在 socket.io@4.4.0 中添加):

¥And finally, the SocketData type is used to type the socket.data attribute (added in socket.io@4.4.0):

io.on("connection", (socket) => {
socket.data.name = "john";
socket.data.age = 42;
});
caution

这些类型提示不会取代输入的正确验证/清理。像往常一样,永远不要相信用户输入。

¥These type hints do not replace proper validation/sanitization of the input. As usual, never trust user input.

客户端的类型

¥Types for the client

在客户端,你可以重用相同的 ServerToClientEventsClientToServerEvents 接口:

¥On the client side, you can reuse the same ServerToClientEvents and ClientToServerEvents interfaces:

import { io, Socket } from "socket.io-client";

// please note that the types are reversed
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io();

同样,发送事件时使用 ClientToServerEvents 接口中声明的事件:

¥Similarly, the events declared in the ClientToServerEvents interface are used when sending events:

socket.emit("hello");

接收事件时使用 ServerToClientEvents 中声明的:

¥And the ones declared in ServerToClientEvents are used when receiving events:

socket.on("noArg", () => {
// ...
});

socket.on("basicEmit", (a, b, c) => {
// a is inferred as number, b as string and c as buffer
});

socket.on("withAck", (d, callback) => {
// d is inferred as string and callback as a function that takes a number as argument
});

每个命名空间的自定义类型

¥Custom types for each namespace

由于每个 命名空间 可以有自己的一组事件,因此你还可以为每个事件提供一些类型:

¥Since each Namespace can have its own set of events, you can also provide some types for each one of them:

import { Server } from "socket.io";

// types for the main namespace
const io = new Server<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>();

// types for the namespace named "/my-namespace"
interface NamespaceSpecificClientToServerEvents {
foo: (arg: string) => void
}

interface NamespaceSpecificServerToClientEvents {
bar: (arg: string) => void;
}

interface NamespaceSpecificInterServerEvents {
// ...
}

interface NamespaceSpecificSocketData {
// ...
}

const myNamespace: Namespace<
NamespaceSpecificClientToServerEvents,
NamespaceSpecificServerToClientEvents,
NamespaceSpecificInterServerEvents,
NamespaceSpecificSocketData
> = io.of("/my-namespace");

myNamespace.on("connection", (socket) => {
socket.on("foo", () => {
// ...
});

socket.emit("bar", "123");
});

在客户端:

¥And on the client side:

import { io, Socket } from "socket.io-client";

const socket: Socket<
NamespaceSpecificServerToClientEvents,
NamespaceSpecificClientToServerEvents
> = io("/my-namespace");

socket.on("bar", (arg) => {
console.log(arg); // "123"
});