Search code examples
typescriptreduxredux-thunk

How to dispatch an Action or a ThunkAction (in TypeScript, with redux-thunk)?


Say I have code like so:

import { Action, Dispatch } from 'redux';
import { ThunkAction } from 'redux-thunk';

interface StateTree {
  field: string;
}

function myFunc(action: Action | ThunkAction<void, StateTree, void>,
                dispatch: Dispatch<StateTree>) {
  dispatch(action); // <-- This is where the error comes from
}

...I get this error from the TypeScript compiler:

ERROR in myFile.ts:x:y
TS2345: Argument of type 'Action | ThunkAction<void, StateTree, void>' is not assignable to parameter of type 'Action'.
  Type 'ThunkAction<void, StateTree, void>' is not assignable to type 'Action'.
  Property 'type' is missing in type 'ThunkAction<void, StateTree, void>'.

I believe the problem is because of the way the redux-thunk type definition file augments the redux Dispatch interface and the inability for TypeScript to know which definition of Dispatch to use.

Is there a way around this?


Solution

  • I think you are correct in that despite being able to handle both types, typescript cannot work out which overload to use.

    I think the best option for you is to cast back to the desired type when calling dispatch

    function myFunc(action: Action | ThunkAction<void, StateTree, void>, 
                    dispatch: Dispatch<StateTree>) {
      if (action instanceof ThunkAction<void, StateTree, void>) {
        dispatch(action as ThunkAction<void, StateTree, void>);
      } else {
        dispatch(action as Action);
      }
    }
    

    I hope I'm wrong and there is a better way to achieve this.