Search code examples
reactjstypescriptuse-reducer

How do I solve the type error "argument is not assignable to parameter of type never" for useReducer hook?


Hovering over the todos variable in my useReducer function here: const [state, dispatch] = useReducer(reducer, todos); gives the following type error.

Argument of type 'TodoState[]' is not assignable to parameter of type 'never'.

I've tried adding TodoState[] as the return type in my reducer function to make sure I'm not accidently returning never[] however, the error still persists:

The following is the relevant code:

interface TodoState {
  id: string;
}

interface TodoAction {
  type?: 'CREATED' | 'DELETED' | 'UPDATED';
  payload?: TodoState;
}

interface TodoReducer {
  state: TodoState[];
  action: TodoAction;
}

interface TodosProviderProps {
  children: ReactChildren;
  todos: TodoState[];
}

const reducer = ({ state = [], action = {} }: TodoReducer): TodoState[] => {
  const { payload, type } = action;

  const mutatedItem = payload;
  if (!mutatedItem) {
    return state;
  }
  const mutatedIndex = state.findIndex((item) => item.id === mutatedItem.id);
  switch (type) {
    case 'CREATED':
      if (mutatedIndex < 0) {
        state.push(mutatedItem);
      }
      break;
    case 'DELETED':
      if (mutatedIndex >= 0) {
        state.splice(mutatedIndex, 1);
      }
      break;
    case 'UPDATED':
      state[mutatedIndex] = mutatedItem;
      break;
    default:
      return state;
  }

  return state;
};

export function TodosProvider({ children, todos }: TodosProviderProps) {
  const [state, dispatch] = useReducer(reducer, todos);// type error for todos here

  // rest of code
}

Solution

  • After going through the docs, I found out, The reducer function is passed two parameters instead of an object that you have destructured.

    So, The line should be:

    const reducer = (state:TodoState[] = [], action:TodoAction = {}): TodoState[] => {