如何解决在Redux-Saga中调用takeEvery()时出现的TypeScript错误?
解决Redux-Saga搭配redux-actions时的TypeScript类型错误
我之前也碰到过一模一样的问题!本质原因是手动定义的action类型和redux-actions生成的实际action类型不兼容——redux-actions的createAction会生成带有固定结构的action对象,你直接写{ payload: { number:number } }没法让TypeScript正确识别它的类型,所以才会报错。
下面是一步步的修正方案,直接套到你的代码里就能解决:
1. 导出正确的Action类型
别自己手动定义action结构,用TypeScript的ReturnType工具类型从你的action creator里自动推导类型,这样能保证100%匹配:
import { createAction, handleActions, Action } from 'redux-actions'; import { delay } from 'redux-saga'; import { all, put, takeEvery } from 'redux-saga/effects'; // 你的action creators保持不变 export const action_creators = { get_action_of_set_number: createAction<{ number: number }>('set_number'), get_action_of_set_number_async: createAction<{ number: number }>('set_number_async') }; // 从action creator提取对应的Action类型 type SetNumberAsyncAction = ReturnType<typeof action_creators.get_action_of_set_number_async>;
2. 修正Saga函数的参数类型
把saga函数里的参数类型换成上面推导出来的SetNumberAsyncAction,代替你手动定义的结构:
function* set_number_async(action: SetNumberAsyncAction) { yield delay(1000); // 这里补全你代码里缺失的action creator调用 yield put(action_creators.get_action_of_set_number(action.payload)); }
3. 完善Reducer和Root Saga的类型适配
顺便把reducer和root saga也调整一下,避免后续再出现类型问题:
// 初始化state(改成initialState更符合Redux规范) const initialState = { number: 0 }; // Reducer部分 export const reducer = handleActions( { // 用actionCreator.toString()获取type,避免手写字符串出错 [action_creators.get_action_of_set_number.toString()]: (state, action: Action<{ number: number }>) => ({ ...state, number: action.payload.number }) }, initialState ); // Root Saga部分 export function* rootSaga() { yield all([ // 同样用toString()获取action type,保证类型匹配 takeEvery(action_creators.get_action_of_set_number_async.toString(), set_number_async) ]); }
几个关键提醒
- 永远不要手动定义action的结构,通过
ReturnType从action creator推导是最靠谱的,能彻底避免类型不匹配。 - 用
actionCreator.toString()代替手写action type字符串,既减少拼写错误,又能让TypeScript帮你做类型检查。
内容的提问来源于stack exchange,提问作者left click
相关产品推荐
相关产品推荐

