Typescript useReducer error solved when adding new state

So, this is just for my reference. previously I had this code.

import { useEffect, useReducer } from "react";
import { questionsApi } from "../constants";
import { Loader } from "../components/Loader";
import { Error } from "../components/Error";
import { StartScreen } from "../components/StartScreen";
import { Question } from "../components/Question";

interface Question {
  correctOption: number;
  id: number;
  options: string[];
  points: number;
  question: string;
}

export enum ActionType {
  DATA_RECEIVED,
  DATA_FAILED,
  START,
}

interface State {
  questions: [] | Question[];
  status: QuestionsStatus;
}

enum QuestionsStatus {
  LOADING,
  READY,
  ERROR,
  ACTIVE,
  FINISHED,
}

type Action =
  | { type: ActionType.DATA_RECEIVED; payload: Question[] }
  | { type: ActionType.DATA_FAILED }
  | { type: ActionType.START };

const initialState: State = {
  questions: [],
  status: QuestionsStatus.LOADING,
};

const reducer = (state: State, action: Action) => {
  const { type } = action;
  switch (type) {
    case ActionType.DATA_RECEIVED:
      return { questions: action.payload, status: QuestionsStatus.READY };
    case ActionType.DATA_FAILED:
      return { ...state, status: QuestionsStatus.ERROR };
    case ActionType.START:
      return { ...state, status: QuestionsStatus.ACTIVE };
    default:
      return { ...state };
  }
};

export const QuizContext = () => {
  const [{ questions, status }, dispatch] = useReducer(reducer, initialState);

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const resp = await fetch(questionsApi);
        const questions = await resp.json();
        dispatch({ type: ActionType.DATA_RECEIVED, payload: questions });
      } catch (error) {
        dispatch({ type: ActionType.DATA_FAILED });
      }
    };

    fetchUsers();
  }, []);

  return (
    <>
      {status === QuestionsStatus.LOADING && <Loader />}
      {status === QuestionsStatus.ERROR && <Error />}
      {status === QuestionsStatus.READY && (
        <StartScreen numQuestions={questions.length} dispatch={dispatch} />
      )}
      {status === QuestionsStatus.ACTIVE && <Question />}
    </>
  );
};

I wanted to add a new state called answer in the initialState and its type definition. As soon as I added this new state in initialState, I got a typescript error inside the component where I was using reducer. The error was:

No overload matches this call.
  Overload 1 of 5, '(reducer: ReducerWithoutAction<any>, initializerArg: any, initializer?: undefined): [any, DispatchWithoutAction]', gave the following error.
    Argument of type '(state: State, action: Action) => { questions: Question[]; status: QuestionsStatus; } | { status: QuestionsStatus; questions: [] | Question[]; answer: number; }' is not assignable to parameter of type 'ReducerWithoutAction<any>'.
      Target signature provides too few arguments. Expected 2 or more, but got 1.
  Overload 2 of 5, '(reducer: (state: State, action: Action) => { questions: Question[]; status: QuestionsStatus; } | { status: QuestionsStatus; questions: [] | Question[]; answer: number; }, initialState: never, initializer?: undefined): [...]', gave the following error.
Argument of type 'State' is not assignable to parameter of type 'never'.ts(2769)

The second place where I got the error was wherever I was using the dispatch function.

The code after adding the new state was:

import { useEffect, useReducer } from "react";
import { questionsApi } from "../constants";
import { Loader } from "../components/Loader";
import { Error } from "../components/Error";
import { StartScreen } from "../components/StartScreen";
import { Question } from "../components/Question";

interface Question {
  correctOption: number;
  id: number;
  options: string[];
  points: number;
  question: string; // question?: string fixes all TS errors.
}

export enum ActionType {
  DATA_RECEIVED,
  DATA_FAILED,
  START,
  NEW_ANSWER,
}

type State = {
  questions: [] | Question[];
  status: QuestionsStatus;
  answer: number;
};

enum QuestionsStatus {
  LOADING,
  READY,
  ERROR,
  ACTIVE,
  FINISHED,
}

type Action =
  | { type: ActionType.DATA_RECEIVED; payload: Question[] }
  | { type: ActionType.DATA_FAILED }
  | { type: ActionType.START }
  | { type: ActionType.NEW_ANSWER; payload: number };

const initialState: State = {
  questions: [],
  status: QuestionsStatus.LOADING,
  answer: 0,
};

const reducer = (state: State, action: Action) => {
  const { type } = action;
  switch (type) {
    case ActionType.DATA_RECEIVED:
      return { questions: action.payload, status: QuestionsStatus.READY };
    case ActionType.DATA_FAILED:
      return { ...state, status: QuestionsStatus.ERROR };
    case ActionType.START:
      return { ...state, status: QuestionsStatus.ACTIVE };
    case ActionType.NEW_ANSWER:
      return { ...state, answer: action.payload };
    default:
      return { ...state };
  }
};

export const QuizContext = () => {
  // got the error here on useReducer
  const [{ questions, status }, dispatch] = useReducer(reducer, initialState);

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const resp = await fetch(questionsApi);
        const questions = await resp.json();
        dispatch({ type: ActionType.DATA_RECEIVED, payload: questions });
      } catch (error) {
        dispatch({ type: ActionType.DATA_FAILED });
      }
    };

    fetchUsers();
  }, []);

  return (
    <>
      <button
        onClick={() => dispatch({ type: ActionType.NEW_ANSWER, payload: 1 })}
      >
        New Answer {}
      </button>
      {status === QuestionsStatus.LOADING && <Loader />}
      {status === QuestionsStatus.ERROR && <Error />}
      {status === QuestionsStatus.READY && (
        <StartScreen numQuestions={questions.length} dispatch={dispatch} />
      )}
      {status === QuestionsStatus.ACTIVE && <Question />}
    </>
  );
};

How I fixed it ?(temporary)

I just added a conditional type for this new state. I just added a question mark. I want to know how this works.

type State = {
  questions: [] | Question[];
  status: QuestionsStatus;
  answer?: number;
};

How I fixed it ?(Really)

Do you see the first switch condition !? I didn't spread the previous state. So if you spread the previous state and override with adding new state properties, this whole mess goes away. Here is the code:

const reducer = (state: State, action: Action) => {
  const { type } = action;
  switch (type) {
    case ActionType.DATA_RECEIVED:
      return { ...state, questions: action.payload, status: QuestionsStatus.READY };
    case ActionType.DATA_FAILED:
      return { ...state, status: QuestionsStatus.ERROR };
    case ActionType.START:
      return { ...state, status: QuestionsStatus.ACTIVE };
    case ActionType.NEW_ANSWER:
      return { ...state, answer: action.payload };
    default:
      return { ...state };
  }
};