Using subscribeWithSelector and immer middleware
See original GitHub issueI am using v4.0 (TS 4.5.5) and trying the standard immer middleware and subscribeWithSelector:
export const store = create<
Store
>()(subscribeWithSelector(immer((set, get) => createRootSlice(set, get))));
but I got this error:
TS4023: Exported variable 'store' has or is using name 'StoreSubscribeWithSelector' from external module "zustand/middleware/subscribeWithSelector" but cannot be named.
Am I doing something wrong, or it is a problem with Zustand v4?
Issue Analytics
- State:
- Created a year ago
- Comments:14 (9 by maintainers)
Top Results From Across the Web
Using middlewares - zfy - React Native Modalfy
This snippet is only provided as an example to show you how to integrate a zustand middleware. You shouldn't rely on devtools as...
Read more >Recipes - Zustand Documentation - Pmndrs.docs
You can, but bear in mind that it will cause the component to update on every ... If you need to subscribe with...
Read more >zustand - npm
Bear necessities for state management in React. Latest version: 4.1.5, last published: 13 days ago. Start using zustand in your project by ...
Read more >GitHub - sthose/zustand: Bear necessities for state management in ...
If you need to subscribe with selector, subscribeWithSelector middleware will help. ... import produce from 'immer' const useStore = create(set => ({ lush: ......
Read more >Daishi Kato on Twitter: "Zustand v3.6.0 is now released! - Twitter
... changed/improved/tricked - New middleware `subscribeWithSelector` ... `subscribeWithSelector` Deprecated features will be removed in v4.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Actually I realized TS4023 occurs only for
subscribeWithSelector
(and not for other middlewares) because that’s the only middleware that uses interface for intermediate types instead of type alias. So we can fix it forsubscribeWithSelector
by using a type alias (and we’re already using them instead of interfaces in most places, I usually prefer interface but in this case I think type aliases are fine).But the .d.ts files still look a bit ugly as it inlines all the types (as it does now also for other middlewares) but I guess that’s okay.
So I’ll open a PR for using type aliases.
The problem is with
--declaration
TS emits .d.ts files which looks something like this…Now to write the actual type instead of
TheType
TS needsStoreSubscribeWithSelector
in the scope, which it isn’t right now hence it complains.But
useStore
’s type actually never directly usesStoreSubscribeWithSelector
, it’s type actually is this…It only later resolves to a type that uses
StoreSubscribeWithSelector
. So typescript should emit the above type, not the one it resolves to (this might be a bug in TS).So one workaround is to explicitly type
useStore
with the above type and then TS will emit that…This will compile, as you can see here.
Another solution could be that we export
StoreSubscribeWithSelector
(and the many other types) but that still won’t solve the problem as you’ll also have to import them to bring them in the scope (even if you’re not using them). But even that is problematic because we don’t want to export our intermediate types nor .d.ts should emit them as they are not to consumed directly.And of course if you can remove
--declaration
then the problem gets solved entirely.I personally think it’d make sense that the users explicitly annotate the exports instead of us exporting the types and making a compromise. But I’ll let @dai-shi take the call if we want
--declaration
(which isfalse
by default) users to annotate their exports or we should export those our types.