How to type useSelector in a shared Redux Toolkit slice inside an Nx monorepo when the component doesn't know the app’s RootState? #5145
-
|
I'm using Redux Toolkit in an Nx monorepo and I have a shared component that lives in a library and is used across multiple apps. The problem is typing: Because of this, I'm falling back to the untyped useSelector, but that leads to errors like:
Example: import { useSelector } from 'react-redux';
const isVisible = useSelector((state) =>
selectIsTutorialStepVisible(state, 'select')
);Is there a recommended way to type useSelector (or selectors in general) inside a shared component that does not have access to the application's RootState? Should slices in shared libs define their own RootState fragment types somehow, or is using the untyped useSelector the expected approach in this scenario? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 9 replies
-
|
At that point, yeah, you're better off just supplying a sort of partial "NotQuiteRootState" type that only reflects what the component expects will be in the store. Not truly typesafe, in that it's not coming from the actual constructed store, but it's the best you can get when you're mixing essentially dynamic app construction with static typing. |
Beta Was this translation helpful? Give feedback.
-
|
I have a question on this NX context. What is the type of On libs/features-a, I have featureAQuery. My utility functions need to pass the import { queryApi } from '@org/store-data-access';
import { getSomeData } from './feature-a.services';
import { SomeDataResponse } from './feature-a.types';
export const meQueryApi = queryApi.injectEndpoints({
endpoints: (builder) => ({
getMe: builder.query<SomeDataResponse, void>({
queryFn: async () => {
try {
const result = await getSomeData();
return { data: result };
} catch (error) {
return { error };
}
},
}),
}),
});
export const someFunction = async (
/**
* TODO: typing for dispatch, SlicedQueryRootDispatch
*/
dispatch: (arg: any) => Promise<{ data: Data | undefined }>
) => {
const { data: myData } = await dispatch(
myQueryApi.endpoints.someEndpoints.initiate()
);
if (!myData) {
throw redirect(getPath('home'));
}
return myData;
};
export const clientLoader: ClientLoaderFunction = async () => {
await someFunction(store.dispatch);
return null;
}; |
Beta Was this translation helpful? Give feedback.
for slices you know will be mounted under their name/reducerPath, we export a
WithSlicehelper:For other locations you'd have to be a bit more manual: