Reputation: 1163
I am struggling to figure out what the return type should be for my action. Everything works whilst I am using any
but am trying to avoid using any
.
export const saveValue = (value: number): any => {
return (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
const someValueFromState = getState().stateValue;
const payload = {...response, someValueFromState}
dispatch({ type: constants.SAVE_VALUE, payload });
});
};
};
I had it working before when the action was not using getState()
and it looked like this, where it returned Dispatch<SaveValue>
:
export const saveValue = (value: number): Dispatch<SaveValue> => {
return (dispatch: Dispatch<SaveValue>): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
dispatch({ type: constants.SAVE_VALUE, response });
});
};
};
But once I added getState, I am not sure what to do anymore. I have tried to put the return value in a variable and can see the object I am creating is const myAttempt: (dispatch: Dispatch<SaveValue>, getState: () => State) => void
but when I tried to use it as follows, it doesn't work:
export const saveValue = (value: number): (dispatch: Dispatch<SaveValue>, getState: () => StoreState) => void => {
return (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
const someValueFromState = getState().stateValue;
const payload = {...response, someValueFromState}
dispatch({ type: constants.SAVE_VALUE, payload });
});
};
};
Doing this, I get an error: A function whose declared type is neither 'void' nor 'any' must return a value.
EDIT:
Just to add, I cannot return Dispatch<SaveValue>
as I was before, otherwise I get this error: Type '(dispatch: Dispatch<SaveValue>, getState: () => State) => void' is not assignable to type 'Dispatch<SaveValue>'
Upvotes: 5
Views: 15550
Reputation: 51
First configure the following in your store:
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
then, in your function use the previously custom types
export const getUserRolUid = () => {
return async (dispatch: AppDispatch, getState: ()=> RootState) => {
const { uid } = getState().auth;
const user = await loadUser(uid);
if (user) {
// update the role and send the data to redux
dispatch(getUser(user));
} else {
dispatch(getUserRolUid());
}
};
}
Upvotes: 5
Reputation: 1163
A friend helped me answer this. This was the right way to do it:
export const saveValue = (value: number): (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
return (dispatch: Dispatch<SaveValue>, getState: () => State): void => {
axios.post('www.exampleurl.com', value)
.then((response) => {
const someValueFromState = getState().stateValue;
const payload = {...response, someValueFromState}
dispatch({ type: constants.SAVE_VALUE, payload });
});
};
};
The issue I was having was with my mapDispatchToProps
function which was being explicitly typed and causing the error Type '(dispatch: Dispatch<SaveVisit>, getState: () => StoreState) => void' is not assignable to type 'Dispatch<SaveVisit>'
. The function was:
interface MapDispatchToPropsInterface {
saveValue : (value: number) => Dispatch<SaveValue>;
}
const mapDispatchToProps: MapDispatchToPropsInterface = {
saveValue : ActionCreators.saveValue,
};
but the interface needed to be:
interface MapDispatchToPropsInterface {
saveValue : (saveDetails: CheckedVisit) => (dispatch: Dispatch<SaveValue>, getState: () => StoreState) => void;
}
Upvotes: 9