I am using reduxjs/toolkit
to set up my redux store and I would like to enforce that whenever dispatch
is called, it only accepts actions that I have declared in my slices:
import { combineReducers, configureStore, createSlice } from "@reduxjs/toolkit";
const initialState = {
value: false,
};
const testSlice = createSlice({
name: "test",
initialState,
reducers: {
toggled(state) {
state.value = !state.value;
},
},
});
const appReducer = combineReducers(testSlice.reducer);
const store = configureStore({
reducer: appReducer,
});
const MyComponent = () => {
const dispatch = useDispatch();
handleClick() {
dispatch(someInvalidAction()) // does not complain
dispatch(toggled())
}
}
I am aware that I could just pass a generic typeof testSlice.actions
to dispatch
or have a combined union including all the action types like type AllActions = typeof testSlice.actions | typeof otherSlice.actions
, but it feels like there should be a more straight forward way of doing this or perhaps someone knows the reason why it does not work like that out of the box?
Just don't do it. This simulates some kind of type safety that just doesn't exist in your application - internally, Redux will dispatch additional actions (e.g. INIT), and also all of your middleware might dispatch actions on their own.
Having the dispatch type of your store as shown in https://redux-toolkit.js.org/usage/usage-with-typescript#getting-the-dispatch-type is really the most realistic you can get.
const store = configureStore({ reducer: rootReducer, }) export type AppDispatch = typeof store.dispatch export const useAppDispatch = useDispatch.withTypes<AppDispatch>()