I have this setup for Redux (Zustand) store
type StateType = keyof DatasetSlice | keyof GlobalSlice
type Slices = GlobalSlice & DatasetSlice
const setStore = set => ({
...datasetSlice(set),
...globalSlice(set),
})
const useStore = create(devtools<Slices>(setStore, { enabled: true, name: 'Core store' }))
export const useGetStates = (stateKeys: StateType[]) =>
useStore(
state =>
Object.assign(
{},
...stateKeys.map(stateKey => {
return { [stateKey]: state[stateKey] }
})
),
shallow
)
useGetStates is used to fetch data from the store, like this
const { backButtonTarget, invitedUsers } = useGetStates(['backButtonTarget', 'invitedUsers'])
The problem is that fetched variables (backButtonTarget, invitedUsers) have ANY type, but I need their types as they are defined in the store. Any ideas how it can be solved here?
You can achieve the desired result by adding the generic parameters to useGetStates
:
export const useGetStates = <T extends StateType[]>(
stateKeys: T,
): { [K in T[number]]: Slices[K] } =>
useStore(
(state) =>
Object.assign(
{},
...stateKeys.map((stateKey) => {
return { [stateKey]: state[stateKey] };
}),
),
shallow,
);
The crucial part is the return type which takes the elements from the passed array and assigns their slice type as a value:
{ [K in T[number]]: Slices[K] }