Closed
Description
The overloading of Dispatch
by redux-thunk
breaks middlewares that only handle standard action objects (as apposed to thunks).
Example:
import {Action, Dispatch, Middleware, Store} from 'redux';
import {IAppState} from '../reducers';
export const middleware: Middleware = (store: Store<IAppState>) => (next: Dispatch<IAppState>) => (action: Action) => {
// Do something with the action ...
next(action);
};
The resulting error is:
Type '(store: Store<IAppState>) => (next: Dispatch<IAppState>) => (action: Action) => void' is not assignable to type 'Middleware'.
Type '(next: Dispatch<IAppState>) => (action: Action) => void' is not assignable to type '(next: Dispatch<any>) => Dispatch<any>'.
Type '(action: Action) => void' is not assignable to type 'Dispatch<any>'.
Types of parameters 'action' and 'asyncAction' are incompatible.
Type '(dispatch: Dispatch<any>, getState: () => any, extraArgument: any) => any' is not assignable to type 'Action'.
Property 'type' is missing in type '(dispatch: Dispatch<any>, getState: () => any, extraArgument: any) => any'.
A possible fix to remove the compiler error would be to declare a union type for the Action, i.e. Action | Redux.ThunkAction<any, IAppState, any>
:
export const middleware: Middleware = (store: Store<IAppState>) => (next: Dispatch<IAppState>) => (action: Action | Redux.ThunkAction<any, IAppState, any>) => {
// Do something with the action ...
next(action as Action);
};
But this is incorrect if your middleware only handles Action
!
The better solution would be to declare a Dispatch
interface within the redux-thunk
module that extends Redux.Dispatch
. This Dispatch
could then be used in action creators that return a ThunkAction
:
import {IAppState} from '../reducers';
import {ThunkAction, Dispatch} from 'redux-thunk';
export function thunkedActionCreator(): ThunkAction<void, IAppState, void> {
return (dispatch: Dispatch<IAppState>, getState: () => IAppState): void => {
// Do something async and dispatch actions or other thunks ...
};
}
Middlewares on the other hand would use Redux.Dispatch
(see middleware example above).
Metadata
Metadata
Assignees
Labels
No labels