Как вручную написать объединенный редуктор с Typescript? - PullRequest
0 голосов
/ 06 июля 2018

Я учу редук с машинописью.До тех пор, пока я не нажал наcellReducer,

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};
}

пока BAction вызывается на reducerA и reducerC, они ничего не делают и просто возвращают свое собственное состояние.

1 Ответ

0 голосов
/ 07 июля 2018

Проблема в том, что функция isAAction просто возвращает логическое значение, но Typescript не может знать, что это логическое значение указывает тип действия.

Первое решение - просто приведите его к действию:

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

Второе решение - заменить isAAction метод на typeguard, тогда Typescript будет знать, что эта функция возвращает true, когда AAction передается в качестве аргумента

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;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...