It can be done without useShallow, and with type safety. Expanding on @TheTisiboth 's response, because he seemingly called a hook inside a callback, and also typescript didn't know which keys were passed when guessing the keys of the returned object.
For me this worked:
const useMultiple = <T extends object, K extends keyof T>(
useStoreFn: UseBoundStore<StoreApi<T>>,
...items: Array<K>
): { [P in K]: T[P] } =>
useStoreFn((state) => {
return items.reduce(
(carry, item) => ({
...carry,
[item]: state[item],
}),
{},
) as { [P in K]: T[P] }
})
export const useStoreMultiple = <K extends keyof (GlobalState & Actions)>(
...items: Array<K>
): { [P in K]: (GlobalState & Actions)[P] } => {
return useMultiple(useStore, ...items)
}
so now if you try to destructure with a key that you did not pass to useStoreMultiple
you will get an error from your IDE