question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TypeScript type conflict with persist middleware

See original GitHub issue

I am unable to get the persist middleware working with TypeScript if I define state properties with multiple types or with the boolean type.

zustand version: 3.6.4 TypeScript version: 4.1.3

Example code:

import create, { GetState, SetState } from "zustand";
import { persist, StoreApiWithPersist } from "zustand/middleware";

type AuthStore = {
  token: string | undefined;
  authenticated: boolean;
  authenticate: (username: string, password: string) => Promise<void>;
}

const useAuthStore = create<AuthStore, SetState<AuthStore>, GetState<AuthStore>, StoreApiWithPersist<AuthStore>>(
  persist(
    (set) => ({
      token: undefined,
      authenticated: false,
      authenticate: async (username, password) => {
        set({authenticated: true})
      },
    }),
    { name: "auth-store" }
  )
);

export default useAuthStore;

persist function gives the following errors:

 Type 'string | undefined' is not assignable to type 'undefined'.
          Type 'string' is not assignable to type 'undefined'.ts(2345)

 The types of 'authenticated' are incompatible between these types.
        Type 'boolean' is not assignable to type 'false'.ts(2345)

Everything works as expected if I just define token and authenticated as any type.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

11reactions
dai-shicommented, Nov 11, 2021

Here’s another workaround:

    type MyState = {
      token: string | undefined
      authenticated: boolean
      authenticate: (username: string, password: string) => Promise<void>
    }
    type MyPersist = (
      config: StateCreator<MyState>,                                            
      options: PersistOptions<MyState>                                          
    ) => StateCreator<MyState>                                                  
    const useStore = create<MyState>(                                           
      (persist as MyPersist)(                                                   
        (set) => ({                                                             
          token: undefined,                                                     
          authenticated: false,                                                 
          authenticate: async (_username, _password) => {                       
            set({ authenticated: true })                                        
          },                                                                    
        }),                                                                     
        { name: 'auth-store' }                                                  
      )                                                                         
    )

Basically, we type cast to that of v3.6.2 which didn’t have persist api. I will modify #651 to show this as a possible workaround.

2reactions
dai-shicommented, Nov 10, 2021

Thanks for reporting. With v3.6.5, if you don’t need the persist api types, you should be able to do this:

const useAuthStore = create<AuthStore>(
  persist(
    (set) => ({
      token: undefined,
      authenticated: false,
      authenticate: async (username, password) => {
        set({authenticated: true})
      },
    }),
    { name: "auth-store" }
  )
);

If you need a custom store api type, it’s a bit tricker. see #632 and: https://github.com/pmndrs/zustand/blob/21a28ff13eb3d13f2944642287e136de998dd8ab/tests/middlewareTypes.test.tsx#L573

Read more comments on GitHub >

github_iconTop Results From Across the Web

zustand typescript persist how to type store - Stack Overflow
import create, { GetState, SetState } from 'zustand'; import { devtools, persist, StoreApiWithPersist } from 'zustand/middleware'; ...
Read more >
class-transformer - npm
TypeScript icon, indicating that this package has built-in type ... Its ES6 and Typescript era. ... npm install class-transformer --save.
Read more >
Express multer middleware
Português (Portuguese Brazil). Installation. $ npm install --save multer. Usage. Multer adds a body object and a file ...
Read more >
Handling errors in Mongoose/Express to display in React | by JB
Our error handling middleware is going to be long so I'm going to save the function in a separate file. The error handling...
Read more >
48 answers on StackOverflow to the most popular Angular ...
To get this to work with typescript 2.0.0, I did the following. npm install --save-dev @types/core-js. tsconfig.json " ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found