Search code examples
reactjstypescriptreduxredux-thunk

Redux action return type when using dispatch and getState


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>'


Solution

  • 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;
    }