I am learning Typescript and I am trying to implement a simple React/Redux app. When I use sync actions it works fine, but the problems are with the async action. I am following the official redux tutorial.
First I declare the state for the session
export interface UserSessionState {
loggedIn: boolean;
}
Then I declare the interface for the action
interface UpdateSessionAction {
type: 'USER_LOGIN';
payload: boolean;
}
I export them with Union Types
export type UserActionTypes = UpdateSessionAction;
Then I have the actual Action
export function updateSession(loggedIn: UserSessionState) {
return {
type: 'USER_LOGIN',
payload: loggedIn,
};
}
I have a fake api call
function api() {
return Promise.resolve(true);
}
And finally the login
export const userLogin = (): ThunkAction<
void,
{},
{},
AnyAction
> => async (dispatch: ThunkDispatch<{}, {}, AnyAction>) => {
const res = await api();
dispatch(updateSession({ loggedIn: res }));
};
In the reducer I simply initialize the state
initialState: UserSessionState = {loggedIn: false}
Then I do the normal redux stuff for the reducer.
Finally in my store I call the initial action for checking the state
store.dispatch(userLogin());
I keep getting this error:
Argument of type 'ThunkAction<Promise<void>, {}, {}, AnyAction>' is not assignable to parameter of type 'AnyAction'.
Property 'type' is missing in type 'ThunkAction<Promise<void>, {}, {}, AnyAction>' but required in type 'AnyAction'.
I am missing a type
but I have no idea what I do wrong.
The benefit of Redux-Saga in comparison to Redux-Thunk is that you can more easily test your asynchronous data flow. Redux-Thunk, however, is great for small projects and for developers who just entered into the React ecosystem. The thunks' logic is all contained inside of the function.
Redux-Thunk is the most popular middleware that manages asynchronous actions in Redux.
In short:
You get this error because what returned from your userLogin()
function is a ThunkAction
, which is missing type
Why this is happening?
dispatch should accept parameter of type AnyAction
.
AnyAction
is a redux type, which extends Action
(which have a mandatory property type
).
This is from the current redux types file
export interface Action<T = any> {
type: T
}
/**
* An Action type which accepts any other properties.
* This is mainly for the use of the `Reducer` type.
* This is not part of `Action` itself to prevent users who are extending `Action.
*/
export interface AnyAction extends Action {
// Allows any extra properties to be defined in an action.
[extraProps: string]: any
}
How to fix it?
Use ThunkDispatch
type instead of redux's standard Dispatch
. The following example and more can be found on this Gist
const mapDispatchToProps = (dispatch: ThunkDispatch<MyState, void, Action>) => {
return {
onRequestClick: (arg: any) => dispatch(myAsyncAction(arg)),
};
}
Also, see this article, section Map Dispatch to Props
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With