Search code examples
typescriptredux

Error about matching override when trying to use simple redux reducer to set boolean value


Doing this project to help myself learn Redux and Typescript, so very much still on the learning curve there.

Following what I read in a book, I have a "slice" set up which contains the definitions for reducers:

const iState: { value: Book[], formShown: boolean } = { value: [], formShown : false };

export const cartSlice = createSlice({
    name : 'cart',
    initialState : iState,
    reducers : {
        addBookToCart : (state, action) => {            
            state.value.push(action.payload);
        },
        showForm: (state, action) => {
            state.formShown = true;
        }
    }
});

The first reducer (addBookToCart) works fine, but the second one doesn't. It shouldn't really need any parameters at all; it's just setting a boolean "on" switch. But whatever I try to feed it, I get an error.

Here's the relevant code there:

const showForm = (e : React.MouseEvent<HTMLElement>) => {
        e.preventDefault();
        dispatch(showForm(true));
    };
    
    if (itemList.length) {
        return (
            <>
                <ul>
                    {itemList}
                </ul>
                <p><b>Total Price: ${totalPrice.toFixed(2)}</b></p>
                <br />
            {
                formShown ? <PaymentForm />
                        : <Button variant="success" onClick={showForm}>Checkout</Button>
            }
                
            </>
        );
    } 
    else {
        return (<p><b>Your Shopping Cart is Empty</b></p>);
    }

And this is the error I get (immediately as the code compiles in the IDE):

ERROR in src/Cart.tsx:64:18

TS2769: No overload matches this call.
  Overload 1 of 3, '(thunkAction: ThunkAction<unknown, { page: { value: string; }; books: { value: Book[]; }; ajax: { value: string; }; cart: { value: Book[]; formShown: boolean; }; }, undefined, AnyAction>): unknown', gave the following error.
    Argument of type 'void' is not assignable to parameter of type 'ThunkAction<unknown, { page: { value: string; }; books: { value: Book[]; }; ajax: { value: string; }; cart: { value: Book[]; formShown: boolean; }; }, undefined, AnyAction>'.
  Overload 2 of 3, '(action: AnyAction): AnyAction', gave the following error.
    Argument of type 'void' is not assignable to parameter of type 'AnyAction'.
  Overload 3 of 3, '(action: AnyAction | ThunkAction<unknown, { page: { value: string; }; books: { value: Book[]; }; ajax: { value: string; }; cart: { value: Book[]; formShown: boolean; }; }, undefined, AnyAction>): unknown', gave the following error.
    Argument of type 'void' is not assignable to parameter of type 'AnyAction | ThunkAction<unknown, { page: { value: string; }; books: { value: Book[]; }; ajax: { value: string; }; cart: { value: Book[]; formShown: boolean; }; }, undefined, AnyAction>'.
    62 |     const showForm = (e : React.MouseEvent<HTMLElement>) => {
    63 |         e.preventDefault();
  > 64 |         dispatch(showForm(true));
       |                  ^^^^^^^^^^^^^^
    65 |      };
    66 |     
    67 |     if (itemList.length) {

Solution

  • showForm is both the name of an event handler callback function and the name of an action. The syntax coloring of the slice might suggest that the showForm action was never exported (and therefore never imported into the component that uses it).

    The showForm action can be called without any arguments. The action parameter can be removed from the showForm reducer. So, showForm could be updated as follows:

    showForm: (state) => {
        state.formShown = true;
    }