TypeScript在redux-saga错误处理中定义action内error类型的技术问题
redux-saga 结合TypeScript开发时的error类型适配方案
报错根因
- 触发ts(7044)的核心原因是项目开启了
noImplicitAny严格检查,所有未显式标注类型的参数、捕获值都会被识别为隐式any,不符合TS严格模式的规则 - 现有代码里action的错误创建函数入参、WorkerSaga的入参、catch块捕获的error值都没有显式类型标注,因此直接触发告警
合法的error类型定义边界
需要结合运行时特性和FSA规范确定类型,不能随意写:
- JS运行时的
throw语句允许抛出任意类型的值,不一定是Error类的实例,因此不能默认把catch捕获的值直接等价为Error类型 - 遵循Flux Standard Action(FSA)规范的错误动作,要求
error字段设为true,且payload必须是Error实例,方便后续统一读取错误信息、堆栈等通用字段
分模块的代码修复方案
1. action.ts 错误动作创建函数的类型修正
给error入参显式标注为Error类型,匹配FSA规范,消除隐式any问题:
const actionError = (error: Error): IFluxStandardAction => { return { type: ACTIONTYPE_ERROR, payload: error, // 补充FSA规范要求的错误标识 error: true }; };
2. saga.ts WorkerSaga的类型适配
- 给WorkerSaga的入参value标注显式类型,消除隐式any
- catch块捕获的error值,在TS 4.4+开启
useUnknownInCatchVariables配置时默认类型为unknown,不会触发隐式any告警;如果是旧版TS配置,需要显式标注catch块的error为unknown类型 - 传入错误动作前做类型收窄,兼容运行时可能抛出的非Error类型值,保证传给
actionError的参数完全匹配类型要求
对应的实现代码:
function* WorkerSaga(value: { payload: Parameters<typeof clientApi>[0] }) { try { const { payload } = value; const response: Response = yield call(clientApi, payload); yield put(Actions.Success(response)); } catch (error: unknown) { if (error instanceof Error) { // 匹配actionError的入参类型,直接传递 yield put(Actions.Error(error)); } else { // 兼容字符串、数字等非Error类的抛出值,统一包装为Error实例 yield put(Actions.Error(new Error(String(error)))); } } }
常见错误写法踩坑
- 直接给error参数标为
any:虽然能临时消掉类型告警,但完全丢失了类型校验的价值,后续传错值(比如传了字符串、普通对象给payload)也不会有TS提示 - 不做校验直接把catch捕获的error断言为Error:运行时JS支持throw任意值,比如直接
throw "接口请求超时",如果不做类型收窄就断言成Error,后续在reducer里读error.message字段时就会触发运行时报错
内容的提问来源于stack exchange,提问作者Hithesh kumar
相关产品推荐
相关产品推荐

