I’m considering a Vue 3 to React migration at work, and while writing a proof of concept, I’m standardizing the Zustand stores creation, which will all use devtools
and immer
middlewares. And this results in convoluted and error-prone code, which I’m trying to abstract away with a generator function. Such a function, however, has proven to be very hard to write with perfect TypeScript typings.
I had to resort to the great Daishi Kato again, which very patiently helped me to write. It indeed has a deep level of TypeScript black magic which I’m not familiar with:
import {create, StateCreator} from 'zustand';
import {devtools} from 'zustand/middleware';
import {immer} from 'zustand/middleware/immer';
export function createFullStore<T extends object, U extends object>(
name: string,
state: T,
actions: StateCreator<
T,
[['zustand/devtools', never], ['zustand/immer', never]],
[['zustand/immer', never], ['zustand/devtools', never]],
U
>,
) {
return create<T & U>()(
devtools(
immer((...a) => Object.assign({}, state, (actions as any)(...a))),
{name},
),
);
}
It works perfectly, with all the type inferences one would expect. I’m really thankful to the guy.
By the way this should’ve been published yesterday, but after a whole day without internet at home, I finally can do it.