Search code examples
typescriptreact-nativeredux-thunk

dispatch is still expecting an Action even when redux-thunk installed?


I'm trying to use redux-thunk in a TypeScript-based React Native project. My Actions are defined as

export type Action<T> = {
  type: T,
  payload?: any
}

My store is defined as

import { applyMiddleware, createStore } from 'redux'
import { persistStore } from 'redux-persist'
import thunk from 'redux-thunk'

import logger from 'src/redux/middleware/logger'
import rootReducer from 'src/redux/reducers'

export const store = createStore(rootReducer, applyMiddleware(logger, thunk))
export const persistor = persistStore(store)

My action constructor is defined as

export const setRepeat = (repeat: Repeating) => (
  dispatch: Dispatch<Action>,
  getState: () => AppState
) =>
  dispatch<Action>({
    payload: repeat,
    type: actionTypes.SET_REPEAT,
  })

Repeating is a simple enum:

export enum Repeating {
  All = 'all',
  None = 'none',
  Single = 'single',
}

And when I attempt to dispatch this action with

store.dispatch(setRepeat('all' as Repeating))

I get this error

TS2345: Property 'type' is missing in type '(dispatch: Dispatch<Action<string>>, getState: () => AppState) => Action<string>' but required in type 'Action<string>'.

From what I can tell, this means that setRepeat is returning a function (which makes sense, that's what it's defined to do). But store.dispatch is not expecting a function like redux-thunk allows and is still expecting an Action.

I can't seem to find any explanation of why thunk isn't providing correct types here, or what I need to do to correct this problem.

  • react-native: 0.57.7
  • redux: 4.0.1
  • react-redux: 6.0.0
  • redux-thunk: 2.3.0

Solution

  • This issue has been brought up on github

    To summarize, you need to add the types:

    const store = createStore(
    rootReducer,
    applyMiddleware(
        thunk as ThunkMiddleware<IState, Actions>, // this is crucial
    ));
    

    ORIGINAL ANSWER BELOW

    The problem here is that dispatch takes a type of Action<T> which has a property type but you are sending it a function, and functions don't have types. Notice that setRepeat is a function that returns another function.

    store.dispatch(setRepeat('all' as Repeating)(dispatcherInstance,getStateFunction))
    

    I would need to see more of your code but it seems you're going about this a little bit the wrong way.