TheUnreal
TheUnreal

Reputation: 24492

React Conetxt with useReducer + Typescript - 'No overload matches this call'

I have the following reducer code:

import { IState } from "./initialState";
import { TAction } from "./actions";
import * as types from './types';

const reducer = (state: IState, action: TAction): IState => {
    const { type, payload } = action;
    switch (type) {
        case types.API_REQUEST:
            return {
                ...state,
                loading: true
            };
        case types.API_SUCCESS:
            return {
                ...state,
                loading: false,
                data: payload
            };
        case types.API_ERROR:
            return {
                ...state,
                error: payload
            };
        default:
            return state;
    }
};

export default reducer;

Usage in component:

import * as React from "react";
import { useReducer } from "react";
import Context from './newsContext';
import reducer from "./store/reducer";
import initialState from "./store/initialState";
function News(): JSX.Element {
    const [state, dispatch] = useReducer(reducer, initialState);
    return (
        <Context.Provider value={{ state, dispatch }}>
            <h1>Hello World</h1>
        </Context.Provider>);
}

Context:

import initialState, { IState } from "./store/initialState";
import { TAction } from "./store/actions";
import { createContext, Dispatch } from "react";

interface IContextProps {
    state: IState,
    dispatch: Dispatch<TAction>;
}

const Context = createContext<IContextProps>({
    dispatch: () => {
        // Dispatch initial value
    },
    state: initialState
});

export default Context;

My compiler shows ts error:

TypeScript error in reactor-ts/src/news/News.tsx(7,42):
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: IState, action: TAction) => IState' is not assignable to parameter of type 'ReducerWithoutAction<any>'.
  Overload 2 of 5, '(reducer: Reducer<any, any>, initialState: any, initializer?: undefined): [any, Dispatch<any>]', gave the following error.
    Argument of type '(state: IState, action: TAction) => IState' is not assignable to parameter of type 'Reducer<any, any>'.
      Types of parameters 'action' and 'action' are incompatible.
        Type 'any' is not assignable to type 'never'.
          The intersection 'TAction' was reduced to 'never' because property 'type' has conflicting types in some constituents.  TS2769

Any idea what I'm missing - why the compiler fails?

Upvotes: 0

Views: 528

Answers (1)

TheUnreal
TheUnreal

Reputation: 24492

Found the issue - wow it was so hard to understand from the compiler error.

My code was:

export type TAction = IApiRequest & IApiSuccess & IApiError;

But had to be:

export type TAction = IApiRequest | IApiSuccess | IApiError;

The request can be one of the types, not all of them.

Upvotes: 1

Related Questions