0

I have a small problem, typing my Redux Reducer. I know this question, has been generally answered, but I find the solutions lacking, and I would call them more workarounds than anything else.

The Problem: I have a Redux Reducer. Inside it, 3 functions managing state for Loading, Success and Failure, supplying the necessary data or errors in state along the way. And now TS comes into the game. Basically I get this error:

TS2418: Type of computed property's value is
'(state: ImmutableObjectMixin<IState>, { error }: ActionFailure<Type.LIST_ITEMS_FAILURE, HttpError>) => ImmutableObjectMixin<...>',
which is not assignable to type '(state: ImmutableObjectMixin<IState>, action: ActionWithPayload<Type.LIST_ITEMS_SUCCESS, IItems[]>, { error }: ActionFailure<Type.LIST_ITEMS_FAILURE, HttpError>) => ImmutableObjectMixin<...>'.

Types of parameters '__1' and 'action' are incompatible.
Property 'error' is missing in type 'ActionWithPayload<Type.ITEMS_SUCCESS, IItems[]>' but required in type 'ActionFailure<Type.LIST_ITEMS_FAILURE, HttpError>'.

The error appears in the below block:

const ACTION_HANDLERS: {
  [key: string]: (
    state: ImmutableObjectMixin<IState>,
    action: ActionWithPayload<Type.LIST_ITEMS_SUCCESS, IItems[]>,
    { error }: ActionFailure<Type.LIST_ITEMS_FAILURE, HttpError>
  ) => ImmutableObjectMixin<IState>;
} = {
  [Type.LIST_ITEMS_ATTEMPT]: onListFetching,
  [Type.LIST_ITEMS_SUCCESS]: onListFetchingSuccess,
  [Type.LIST_ITEMS_FAILURE]: onListFetchingFailure // This line throws the TS Error
};

Now, I read about providing the error, to all possible properties, or making them all optional, in relevant answers, but they are not really solving my problem.

Here are the functions:

const onListFetching = (state: ImmutableObjectMixin<IState>): ImmutableObjectMixin<IState> =>
  state.merge({
    listFetching: true,
    list: [],
    errorListing: null
  });

const onListFetchingSuccess = (
  state: ImmutableObjectMixin<IState>,
  action: ActionWithPayload<Type.LIST_ITEMS_SUCCESS, IItems[]>
): ImmutableObjectMixin<IState> => {
  const { payload = [] } = action;
  return state.merge({
    listFetching: false,
    list: payload,
    errorListing: null
  });
};

const onListFetchingFailure = (
  state: ImmutableObjectMixin<IState>,
  { error }: ActionFailure<Type.LIST_ITEMS_FAILURE, HttpError>
): ImmutableObjectMixin<IState> =>
  state.merge({
    listFetching: false,
    errorListing: error,
    list: []
  });

Any help typing this would be appreciated. I think the problem, might like on the key property. Since we are restructuring error but I could be wrong. Thanks you..

  • I am providing 3 Parameters. In the exact same order. I do not think I follow.. Sorry.. –  Jan 14 '20 at 22:56
  • I actually, found a way to handle this somehow. I used `Handlers` Generic Interface from `redux-sauce`. Here is the signature: `export interface Handlers {[type: string]: (state: S, action: Action) => S;}` –  Jan 14 '20 at 22:59

1 Answers1

0

Instead of typing it on my own, I used, the Handlers Generic interface, from redux-sauce.

Here is the interface itself:

  export interface Handlers<S> {
    [type: string]: (state: S, action: Action) => S;
  }

It basically does the exact same thing as my typing but it overlaps the TS Error. Not sure why, though. That would be useful to know, if you have the answer.

Here is the new Code:

const ACTION_HANDLERS:Handlers<ImmutableObjectMixin<IState>> = {
  [Type.LIST_ITEMS_ATTEMPT]: onListFetching,
  [Type.LIST_ITEMS_SUCCESS]: onListFetchingSuccess,
  [Type.LIST_ITEMS_FAILURE]: onListFetchingFailure
};

Everything works like a char,. But if it can be improved even more, please let me know..