tonsteri
tonsteri

Reputation: 705

redux reducer flow not inferring type

I ran into a flow error while doing essentially the basic redux-reducer example from flow docs.

Error from flow added to the code here: on the REMOVE switch case: action is not resolved to the correct type.

If i hover over payload in vscode, in the ADD case it displays it as AddAction, but on REMOVE case it is displayed as a union of all the actions, i.e. Action.

What am i missing or understanding wrong? Flow should deduct the correct type down from the Actions union to the only possible type(s) inside if and switch.

// @flow
const initialState = [];

type Item = { id: number, data: string };
type State = Item[];

type AddAction = {
  type: 'ADD',
  payload: Item
};

type RemoveAction = {
  type: 'REMOVE',
  payload: { id: number }
};

type ClearAction = {
  type: 'CLEAR'
};

type Action = AddAction | RemoveAction | ClearAction;

const reducer: (State, Action) => State = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD': {
      return [...state, action.payload];
    }

    case 'REMOVE': {
      return state.filter(t => t.id !== action.payload.id);
                                               ^ property `payload`. Property not found in
    }

    case 'CLEAR': {
      return [];
    }

    default:
      (action: empty);
      return state;
  }
};

export default reducer;

Upvotes: 0

Views: 301

Answers (1)

tonsteri
tonsteri

Reputation: 705

Ok, it seems that the problem was the use of action inside Array.filter arrow function:

If i replace the REMOVE case contents with

case 'REMOVE': {
  const id = action.payload.id;
  return state.filter(t => t.id !== id);
}

the errors go away.

I guess flow cannot infer the type inside the arrow function. Would be interesting to know why.

edit: related question

So, flow invalidates the union refinement because it assumes filter() might be doing side effects to reducer parameter action (docs). Storing the action or payload in a const before using fixes this.

Upvotes: 3

Related Questions