title: Typescript error TS2554: Expected 0 arguments, but got 1. while using useReducer and useContext with React
body: <p>I have a number of useReducers and useContext where I am getting similar errors as the one listed below (TS2554).
  I have picked out the AuthReducer as it is the simplest.
  I get the same error for each Action dispatch. I've toyed around looking at other solutions and trying them out, Added some more definitions but clearly I'm not doing what I'm supposed to be!</p>
  <p>Its my first project that I'm working on with Typescript so go easy on me!</p>
  <p>as far as I can tell Dispatch is not expecting any arguments but is receiving one. However when I declare my AuthReducer it has an action argument of type Actions and returns AuthState.</p>
  <pre><code>/AuthState.tsx:40:16 - error TS2554: Expected 0 arguments, but got 1.
  
  40       dispatch({
  41         type: USER_LOADED,
  42         payload: res.data,
  43       });
  </code></pre>
  <p>AuthReducer.tsx</p>
  <pre><code>import {
    USER_LOADED,
    AUTH_ERROR,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
    LOGOUT,
    CLEAR_ERRORS,
  } from '../types';
  import { initialState } from './AuthState';
  
  type Actions =
    | {
        type: 'USER_LOADED';
        payload: {
          name: string;
          id: string;
        };
      }
    | {
        type: 'AUTH_ERROR';
        payload?: string;
      }
    | {
        type: 'LOGIN_SUCCESS';
        payload: { token: string };
      }
    | {
        type: 'LOGIN_FAIL';
        payload: string;
      }
    | {
        type: 'LOGOUT';
        payload?: string;
      }
    | {
        type: 'CLEAR_ERRORS';
      };
  
  interface AuthState {
    token?: string | null;
    isAuthenticated?: boolean;
    loading: boolean;
    user?: {
      name: string;
      id: string;
    } | null;
    error?: string | undefined | null;
  }
  
  const AuthReducer = (
    state: typeof initialState,
    action: Actions
  ): AuthState =&gt; {
    switch (action.type) {
      case USER_LOADED:
        return {
          ...state,
          isAuthenticated: true,
          loading: false,
          user: action.payload,
        };
      case LOGIN_SUCCESS:
        localStorage.setItem('token', action.payload.token);
        return {
          ...state,
          ...action.payload,
          isAuthenticated: true,
          loading: false,
        };
      case AUTH_ERROR:
      case LOGIN_FAIL:
      case LOGOUT:
        localStorage.removeItem('token');
        return {
          ...state,
          token: null,
          isAuthenticated: false,
          loading: false,
          user: null,
          error: action.payload,
        };
      case CLEAR_ERRORS:
        return {
          ...state,
          error: null,
        };
      default:
        return state;
    }
  };
  
  export default AuthReducer;
  
  </code></pre>
  <p>AuthContext.tsx</p>
  <pre><code>import { createContext } from 'react';
  import { initialState } from './AuthState';
  
  type authContextType = {
    loadUser: () =&gt; Promise&lt;void&gt; | null;
    login: (formData: {
      email: string;
      password: string;
    }) =&gt; Promise&lt;void&gt; | null;
    logout: () =&gt; void;
    clearErrors: () =&gt; void;
  
    error: string | null;
    isAuthenticated: boolean;
    loading: boolean;
    user: {
      name: string;
      id: string;
    };
    token: string;
  };
  
  const authContext = createContext&lt;authContextType&gt;(initialState); //TODO A more robust type is possible
  
  export default authContext;
  
  </code></pre>
  <p>AuthState.tsx</p>
  <pre><code>import React, { useReducer } from 'react';
  import axios from 'axios';
  import AuthContext from './AuthContext';
  import AuthReducer from './AuthReducer';
  import setAuthToken from '../../utils/setAuthToken';
  import {
    USER_LOADED,
    AUTH_ERROR,
    LOGIN_SUCCESS,
    LOGIN_FAIL,
    LOGOUT,
    CLEAR_ERRORS,
  } from '../types';
  
  export const initialState = {
    loadUser: null,
    login: null,
    logout: () =&gt; {},
    clearErrors: () =&gt; {},
  
    token: localStorage.getItem('token'),
    isAuthenticated: null,
    loading: true,
    error: null,
    user: null,
  };
  
  const AuthState: React.FC = ({ children }) =&gt; {
    const [state, dispatch] = useReducer(AuthReducer, initialState);
  
    //Load User
    const loadUser = async () =&gt; {
      if (localStorage.token) {
        setAuthToken(localStorage.token);
      }
  
      try {
        const res = await axios.get('api/auth');
  
        dispatch({
          type: USER_LOADED,
          payload: res.data,
        });
      } catch (err) {
        dispatch({ type: AUTH_ERROR });
      }
    };
    //Login User
    const login = async (formData: { email: string; password: string }) =&gt; {
      const config = {
        headers: {
          'Content-Type': 'application/json',
        },
      };
      try {
        const res = await axios.post('/api/auth', formData, config);
  
        dispatch({
          type: LOGIN_SUCCESS,
          payload: res.data,
        });
  
        loadUser();
      } catch (err) {
        dispatch({
          type: LOGIN_FAIL,
          payload: err.response.data.msg,
        });
      }
    };
    //Logout
    const logout = () =&gt; {
      dispatch({ type: LOGOUT });
    };
    //Clear Errors
    const clearErrors = () =&gt; {
      dispatch({ type: CLEAR_ERRORS });
    };
  
    return (
      &lt;AuthContext.Provider
        value={{
          token: state.token,
          isAuthenticated: state.isAuthenticated,
          loading: state.loading,
          user: state.user,
          error: state.error,
          loadUser,
          login,
          logout,
          clearErrors,
        }}
      &gt;
        {children}
      &lt;/AuthContext.Provider&gt;
    );
  };
  
  export default AuthState;
  
  </code></pre>