如何处理Socket.io回调中GameState或ErrorResponse类型的响应?
解决方案
针对你遇到的联合类型属性访问报错问题,以下是几种实用的处理方案:
1. 带可区分属性的类型守卫(推荐)
给GameState和ErrorResponse添加一个唯一标识字段(比如type),让TypeScript能自动区分类型:
第一步:修改类型定义
// 给GameState添加区分字段 interface GameState { type: 'gameState'; // 原有属性示例: score: number; level: number; } // 给ErrorResponse添加区分字段 interface ErrorResponse { type: 'error'; // 原有属性示例: errorCode: number; message: string; }
第二步:在回调中判断类型
socket.emit(ClientActions.LOAD_GAME_STATE, (response: GameState | ErrorResponse) => { if (response.type === 'gameState') { // TypeScript自动推断response为GameState,可安全访问其属性 console.log(`当前分数:${response.score}`); } else { // 自动推断为ErrorResponse console.error(`加载失败:${response.message}`); } });
2. 使用in操作符判断属性
如果无法修改原有类型定义,可通过检查独有属性是否存在来区分类型:
socket.emit(ClientActions.LOAD_GAME_STATE, (response: GameState | ErrorResponse) => { // 假设score是GameState独有的属性 if ('score' in response) { // 处理GameState console.log(response.level); } else { // 处理ErrorResponse console.log(response.errorCode); } });
3. 封装断言函数
如果类型判断逻辑复杂,可封装成断言函数复用:
// 断言函数:判断是否为GameState function isGameState(res: GameState | ErrorResponse): res is GameState { return (res as GameState).score !== undefined; } // 断言函数:判断是否为ErrorResponse function isErrorResponse(res: GameState | ErrorResponse): res is ErrorResponse { return (res as ErrorResponse).errorCode !== undefined; } // 回调中使用 socket.emit(ClientActions.LOAD_GAME_STATE, (response: GameState | ErrorResponse) => { if (isGameState(response)) { // 处理GameState } else { // 处理ErrorResponse } });
4. 拆分成功/错误回调(视库支持情况)
部分Socket库支持分开传入成功和错误回调,直接避免联合类型问题:
// 示例(需确认你的Socket库是否支持该写法) socket.emit(ClientActions.LOAD_GAME_STATE, (gameState: GameState) => { // 成功回调,直接处理GameState }, (error: ErrorResponse) => { // 错误回调,直接处理ErrorResponse } );
内容的提问来源于stack exchange,提问作者temporary_user_name
相关产品推荐
相关产品推荐

