Redux-Saga调用API后响应类型定义及Unknown Error处理
Next.js 13 + TypeScript 中 Redux-Saga 类型优化方案
一、为 Generator 泛型定义 Response 类型
首先明确 API 响应的结构,先声明对应的类型接口,再通过 Redux-Saga 的 Generator 泛型约束 yield 返回值的类型。
步骤1:定义 API 响应类型
根据实际响应结构创建 TypeScript 接口:
// 定义笔记列表的响应结构 interface NoteListResponse { status: number; data: Array<{ id: string; title: string; content: string; // 补充其他实际返回的字段 }>; // 响应的其他顶层字段也需在此定义 }
步骤2:修改 Generator 泛型参数
Redux-Saga 的 Generator 泛型包含三个参数:
- 第一个参数:Yield 类型,即
yield call(...)返回值的类型,对应CallEffect<NoteListResponse> - 第二个参数:函数返回类型,此 worker 无返回值,填
void - 第三个参数:Next 类型,即调用
next()传入值的类型,无需时填unknown
修改后的 worker 函数:
import { call, put, CallEffect } from 'redux-saga/effects'; function* getNoteListWorker(): Generator<CallEffect<NoteListResponse>, void, unknown> { try { // 直接调用 apiService.get,无需额外包裹 async 函数 const response: NoteListResponse = yield call(apiService.get, "/note/list"); console.log(response); if (response.status === 200) { yield put(NoteAction.getNoteListSuccess(response.data)); } } catch (error) { // 后续处理 error 的 unknown 类型 } }
注意:原代码中把
apiService.get包裹在 async 函数里是多余的,call可直接接收返回 Promise 的函数和参数,类型推导会更准确。
二、处理 Catch 中的 Unknown 类型错误
TypeScript 中 catch 块的 error 默认类型是 unknown,需通过类型收窄安全访问其属性,避免直接断言为 any。
方案:类型收窄判断
假设使用 Axios 作为请求库,可直接利用 AxiosError 类型判断;若为自定义错误,可通过属性检查收窄类型:
import { AxiosError } from 'axios'; // ... 前面的代码 function* getNoteListWorker(): Generator<CallEffect<NoteListResponse>, void, unknown> { try { // ... 请求逻辑 } catch (error) { let errorMessage = '未知错误'; // 1. 判断是否为 Axios 请求错误 if (error instanceof AxiosError) { errorMessage = error.response?.data?.message || '请求失败'; } // 2. 判断是否为普通 Error 实例 else if (error instanceof Error) { errorMessage = error.message; } // 3. 其他未知错误场景 yield put(NoteAction.getNoteListFail(errorMessage)); } }
如果 API 错误响应有固定结构,也可自定义错误类型并通过类型守卫判断:
// 自定义 API 错误类型 interface ApiError { response: { data: { message: string; }; }; } // 类型守卫函数 function isApiError(error: unknown): error is ApiError { return typeof error === 'object' && error !== null && 'response' in error; } // 在 catch 中使用 catch (error) { let errorMessage = '未知错误'; if (isApiError(error)) { errorMessage = error.response.data.message; } else if (error instanceof Error) { errorMessage = error.message; } yield put(NoteAction.getNoteListFail(errorMessage)); }
内容的提问来源于stack exchange,提问作者LXT
相关产品推荐
相关产品推荐

