Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"No overload matches this call" error when setting up ContextApi & useReducer using Typescript

I trying to set up ContextApi & useReducer with typescript. On my "issuesInitialState" variable in useReducer, I get the error:

No overload matches this call. Overload 1 of 5, '(reducer: ({ state, action }: IssueReducer) => {}, initializerArg: never, initializer?: undefined): [never, DispatchWithoutAction]', gave the following error. Argument of type 'IssuesInitialState' is not assignable to parameter of type 'never'. Overload 2 of 5, '(reducer: ({ state, action }: IssueReducer) => {}, initialState: never, initializer?: undefined): [never, Dispatch]', gave the following error. Argument of type 'IssuesInitialState' is not assignable to parameter of type 'never'.ts(2769)

code:

// Store.tsx
type Issue = {
  closeDate: string | null;
  description: string;
  issueId: number;
  lastEditDate: string | null;
  priorityId: string;
  projectId: number;
  reportDate: string;
  statusId: string;
  title: string;
  userId: number;
};

interface IssuesInitialState {
  issues: Issue[];
  issue: Issue;
  issuesByProject: Issue[];
  updateIssue: Issue;
}

const issuesInitialState: IssuesInitialState = {
  issues: [],
  issue: {
    closeDate: "",
    description: "",
    issueId: 0,
    lastEditDate: "",
    priorityId: "",
    projectId: 0,
    reportDate: "",
    statusId: "",
    title: "",
    userId: 0,
  },
  issuesByProject: [],
  updateIssue: {
    closeDate: "",
    description: "",
    issueId: 0,
    lastEditDate: "",
    priorityId: "",
    projectId: 0,
    reportDate: "",
    statusId: "",
    title: "",
    userId: 0,
  },
};

export const IssuesContext = createContext<{
  issuesState: IssuesInitialState;
  issuesDispatch: any;
}>({ issuesState: issuesInitialState, issuesDispatch: () => null });

export function StoreProvider({ children }: any): JSX.Element {
  const [commentsState, commentsDispatch] = useReducer(
    commentsReducer,
    commentsInitialState
  );
  const [issuesState, issuesDispatch] = useReducer(
    issuesReducer,
    issuesInitialState // where the error is!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  );
// IssuesReducer.ts
interface IssueReducer {
  state: IssuesInitialState;
  action: {
    type: string;
    payload: Issue;
  };
}

export const issuesReducer = ({ state, action }: IssueReducer): {} => {
  switch (action.type) {
    case FETCH_ISSUES:
like image 427
webber Avatar asked May 09 '20 09:05

webber


2 Answers

Besides the return type being an empty object, pointed out by Martin Lockett, your reducer is a function taking a single parameter which is an object with properties state and action, when it should actually be a function that takes 2 parameters, first one being the state and the second being the action. It might help you to type your reducer like so:

import { Reducer } from 'react'

type IssuesAction = {
  type: string;
  payload: Issue;
}

export const issuesReducer: Reducer<IssuesInitialState, IssuesAction> = (state, action) => {
  switch (action.type) {
...

like image 79
Thiago Camargo Avatar answered Oct 20 '22 02:10

Thiago Camargo


You have defined your reducer return type as {} which is not compatible with IssuesInitialState as that types' properties are not optional. Define your reducer return type as the state type

like image 23
Martin Lockett Avatar answered Oct 20 '22 02:10

Martin Lockett