MST
星途 面试题库

面试题:TypeScript实现WebSocket双向类型校验在复杂业务场景下的优化

假设在一个实时多人协作的Web应用中,使用TypeScript实现WebSocket双向类型校验。存在多种不同类型的消息,如用户加入房间消息、用户操作消息、系统通知消息等,每种消息都有不同的数据结构。请设计一个可扩展的类型校验和消息处理架构,保证在添加新类型消息时,代码具有良好的可维护性和扩展性,描述设计思路并给出关键代码示例。
49.7万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义消息类型枚举:通过枚举来定义不同类型的消息,方便管理和识别。
  2. 定义消息接口:针对每种消息类型,定义对应的接口,明确其数据结构。
  3. 使用联合类型:将所有消息接口组合成一个联合类型,用于WebSocket消息的统一接收和发送。
  4. 消息处理函数:为每种消息类型定义专门的处理函数,通过消息类型进行分发处理。
  5. 类型守卫:在处理消息时,使用类型守卫来确保消息类型的正确性。

关键代码示例

// 1. 定义消息类型枚举
enum MessageType {
    UserJoin = 'user-join',
    UserAction = 'user-action',
    SystemNotification ='system-notification'
}

// 2. 定义消息接口
interface UserJoinMessage {
    type: MessageType.UserJoin;
    userId: string;
    roomId: string;
}

interface UserActionMessage {
    type: MessageType.UserAction;
    userId: string;
    action: string;
}

interface SystemNotificationMessage {
    type: MessageType.SystemNotification;
    message: string;
}

// 3. 联合类型
type WebSocketMessage = UserJoinMessage | UserActionMessage | SystemNotificationMessage;

// 4. 消息处理函数
function handleUserJoinMessage(message: UserJoinMessage) {
    console.log(`User ${message.userId} joined room ${message.roomId}`);
}

function handleUserActionMessage(message: UserActionMessage) {
    console.log(`User ${message.userId} performed action: ${message.action}`);
}

function handleSystemNotificationMessage(message: SystemNotificationMessage) {
    console.log(`System notification: ${message.message}`);
}

// 5. 类型守卫及消息分发
function handleWebSocketMessage(message: WebSocketMessage) {
    if (message.type === MessageType.UserJoin) {
        handleUserJoinMessage(message);
    } else if (message.type === MessageType.UserAction) {
        handleUserActionMessage(message);
    } else if (message.type === MessageType.SystemNotification) {
        handleSystemNotificationMessage(message);
    }
}

// WebSocket连接示例
const socket = new WebSocket('ws://localhost:8080');
socket.onmessage = (event) => {
    const message: WebSocketMessage = JSON.parse(event.data);
    handleWebSocketMessage(message);
};

// 发送消息示例
const userJoinMessage: UserJoinMessage = {
    type: MessageType.UserJoin,
    userId: '123',
    roomId: 'room1'
};
socket.send(JSON.stringify(userJoinMessage));

扩展性说明

当需要添加新类型的消息时,只需要:

  1. MessageType枚举中添加新的类型。
  2. 定义新类型消息对应的接口。
  3. 将新接口添加到WebSocketMessage联合类型中。
  4. 编写新类型消息的处理函数,并在handleWebSocketMessage中添加类型守卫和分发逻辑。这样就可以在不影响原有代码逻辑的基础上,实现良好的可维护性和扩展性。