I am writing a react application using a modular architecture. Each module is imported outside a single interface.
const authModule: IModule = {
routes,
reducers: {},
};
export type IModule = {
routes?: IRoute[]
reducers:IReducers
};
Then all modules are collected into one in the root module:
const modules:IModule[] = [
authModule,
userModule,
weatherForecastModule,
commonModule,
];
const routs = modules.reduce(
(acc: IRoute[], module) => (!module.routes ? acc : [...acc, ...module.routes]),
[],
);
const reducers = modules.reduce(
(acc: IReducers, module) => ({ ...acc, ...module.reducers }),
{},
);
const rootModule: IModule = {
routes: routs,
reducers,
};
export default rootModule;
From which I add all reducers to the store:
const store = configureStore({
reducer: {
[baseApi.reducerPath]: baseApi.reducer,
...rootModule.reducers,
userReducer,
screenReducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware()
.concat(baseApi.middleware),
devTools: true,
});
setupListeners(store.dispatch);
export default store;
In the process of assembling reducers into one module, their typing is lost, which is why useAppSelector does not show possible reducers
const user = useAppSelector((state) => state.???);
Additional info:
export type RootState = ReturnType<typeof store.getState>;
export type AppStore = typeof store;
export type AppDispatch = AppStore['dispatch'];
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
How fix it?
Simple example: https://codesandbox.io/s/sleepy-wilbur-qj27hs?file=/src/modules/user/index.ts
You will not get around manually assembling the type for the resulting object. There is no way for TypeScript to infer this in any way, considering that your cast to
IModulealready removes all "interesting" type information from them.