如何用Typescript手写CombineReducer?

时间:2018-07-06 10:23:06

标签: reactjs typescript redux

我正在用打字稿学习redux。 直到我按下CombineReducer,

export const reducerBase= combineReducers({
  stateA: reducerA,
  stateB: reducerB,
  stateC: reducerC
});

工作正常,但我无法手写。 目前我正在尝试做的是

function initialState(): BaseState{
  return {
    a: [],
    b: [],
    c: []
  };
}

type AllActions = AAction | BAction | CAction;


// tslint:disable-next-line:no-any
function isAAction(arg: any) {
  return arg.includes('_A');
}

export function reducerBase(
  state: BaseState= initialState(),
  action: AllActions 
): BaseState{
  if (isAAction(action.type)) {
    return { ...state, a: reducerA(state.a, action) }; // here the problem
  }

  return state;
}

AllActions类型不能分配给AAction类型,

我应该如何进行?

正在工作,

export function reducerBase(
  state: BaseState= initialState(),
  action: AllActions 
): BaseState{
  a: reducerA(state.a, action as AAction);
  b: reducerB(state.b, action as BAction);
  c: reducerC(state.c, action as CAction);
  return {a,b,c};
}

在reducerA和reducerC上调用BAction时,它们什么也不做,只是返回了自己的状态。

1 个答案:

答案 0 :(得分:0)

问题是因为isAAction函数仅返回布尔值,所以Typescript无法知道此布尔值指示操作类型。

第一个解决方案-只需将其投放到AAction:

return { ...state, a: reducerA(state.a, action as AAction) };

第二个解决方案-将isAAction方法更改为Typeguard,然后当AAction作为参数传递时,Typescript将知道此函数返回true

function isAAction(action: any): arg is AAction {
  return action.type.includes('_A');
}

// ...

if (isAAction(action)) {
   return { ...state, a: reducerA(state.a, action) };
} 

编辑:引用您的评论。我个人根本不会使用reducerBase减速器,而只是使用以下结构。动作类型将确定应对给定动作做出反应的减速器。

const reducers = {
  stateA: reducerA,
  stateB: reducerB,
  stateC: reducerC
};

export const store = createStore(
  combineReducers(reducers)
);

export function reducerA(state = new StateA(), action: AAction) {
  switch (action.type) {
    case AActionType.SOME_ACTION: return {
      ...state,
      // some changes based on action
    }

    case AActionType.OTHER_ACTION: return {
      ...state,
      // some changes based on action
    }

    default: return state;
  }
}