Reputation: 1879
I'm actually migrating some code to typescript so I'm new in all this type stuff. When I used redux-thunk with regular javascript the dispatch method returned a promise that helped me to handle errors and stuff. The action was this one:
export const login = ({email, password}) => {
return async function (dispatch) {
try {
const result = await api.post(`/auth/login`, {username, password});
return dispatch({type: 'set_user_session', payload: result.data});
} catch (err) {
throw (err.response && err.response.data) || {code: err};
}
};
};
Then I called normally using the useDispatch hook:
const dispatch = useDispatch();
...
dispatch(login({username: "admin", password: "adminpassword1"}))
.then(d => console.log("ok"))
.catch(err => console.log(err));
Now that I migrated the code to typescript, the action now looks like this:
export const login = ({username, password}: Credentials): ThunkAction<Promise<Action>, {}, {}, AnyAction> => {
// Invoke API
return async (dispatch: ThunkDispatch<{}, {}, AnyAction>): Promise<Action> => {
try {
const result = await api.post(`/auth/login`, {username, password});
return dispatch({type: 'set_user_session', payload: result.data});
} catch (err) {
console.log(err);
throw (err.response && err.response.data) || {code: err};
}
}
}
This is executed without problems, but if I try to handle this:
dispatch(login({username: "admin", password: "adminpassword1"}))
.then(d => console.log("ok"))
.catch(err => console.log(err));
I get this error:
TS2339: Property 'then' does not exist on type 'ThunkAction >, {}, {}, AnyAction>'
I tried to read the section about types in Redux but I cannot find the correct way to declare this dispatch function to work as I need it.
https://redux.js.org/recipes/usage-with-typescript
What's worse is that I'm getting this runtime error after the action is execute:
Possible Unhandled Promise Rejection (id: 0):
So the promise is somewhere.
Upvotes: 3
Views: 3018
Reputation: 67459
The basic Dispatch
type does not know about thunks. You need to infer the modified type of store.dispatch
that tells TS that thunks are acceptable, and then it will understand that dispatching the thunk actually returns a promise.
The best option here is to switch over to using our official Redux Toolkit package, and infer the type of store.dispatch
as shown here:
https://redux-toolkit.js.org/tutorials/typescript
Then, you can use that improved Dispatch
type with the useDispatch
hook.
(FWIW, redoing the Redux core docs "Usage with TS" page is on my todo list for the near-ish future)
Upvotes: 5