DEV Community

Discussion on: React Context with useReducer and Typescript.

Collapse
 
elisealcala profile image
Elizabeth Alcalá

Thanks! Yes I know if you have more than three reducers the types for the main reducer can increase, and be hard to manage.
I don't know how to improve the action type, this action has to be a union of product and shoppingCart actions because when using dispatch you can use either of both actions. To know exactly what action I need to use, maybe you could try with generics and conditional types. I think you could pass a generic type through Context to enable just certain types for actions and state. It's an idea, maybe works. I'll try to implement it.

Collapse
 
mannguyen0107 profile image
Man Nguyen

As it turned out your way of doing the combine reducers also works for type-safe all you gotta do is use type assertion ie:

const mainReducer = ({ products, shoppingCart }: InitialStateType, action: ProductActions | ShoppingCartActions) => ({
  products: productReducer(products, action as ProductActions),
  shoppingCart: shoppingCartReducer(shoppingCart, action as ShoppingCartActions),
});
Enter fullscreen mode Exit fullscreen mode

By using the 'as' keyword there you can now get rid of the unions type on the action arg of your reducers

Thread Thread
 
elisealcala profile image
Elizabeth Alcalá

Hey, you are right, type assertion works well in this case, it makes the code look cleaner without the union types.

Thanks a lot.

Collapse
 
mannguyen0107 profile image
Man Nguyen

So I found this on a stack overflow post

function combineReducers(reducers) {
    return (state = {}, action) => {
        const newState = {};
        for (let key in reducers) {
            newState[key] = reducers[key](state[key], action);
        }
        return newState;
    };
}
Enter fullscreen mode Exit fullscreen mode

all you have to do is pass an object with key and value is the reducer. I'm searching about generic to convert this function to be type-safe. But if you have any idea please share. Thank you!