Description
Hi,
I'm wondering how the typescript type definitions for extension via middleware are supposed to work (when extending the types of Action
s that are possible).
For instance, let's take the module redux-thunk (one of the simplest redux middlewares).
It allows you to dispatch a function with type: (Dispatch, ()=>S) => void
, (that is, a function whose first parameter is the dispatch function, and whose second parameter is the getState function).
suppose I have a trivial type definition for redux-thunk:
declare module "redux-thunk" {
import { Middleware } from 'redux';
const thunkMiddleware: Middleware;
export default thunkMiddleware;
}
And I use it in my app to create a store like:
import { Reducer, createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
const myReducer: Reducer<number> = (count, action) => count;
const myStore = createStore(myReducer, applyMiddleware(thunk));
I can't dispatch a redux-thunk function:
// fails with: Argument of type '(dispatch: any) => number' is not assignable to parameter of type 'Action'.
myStore.dispatch(dispatch =>
setTimeout(() =>
dispatch({
type: "INCREMENT_COUNT"
})
, 500)
)
This is a complex api to account for in a type system, since the signature of dispatch
changes depending on what middleware is loaded:
<A extends Action> dispatch(action: A)
becomes:
dispatch(action: Action | ThunkAction)
(where ThunkAction
is (Dispatch, ()=>S) => void
from above.
I'm not really sure immediately how to address this, but I was just wondering if there is an intended way to work with redux middleware.
cc'ing @aikoven @Igorbek @use-strict