diff --git a/docs/guides/typescript.md b/docs/guides/typescript.md index 4568a5a270..f599734571 100644 --- a/docs/guides/typescript.md +++ b/docs/guides/typescript.md @@ -161,6 +161,21 @@ It isn't really a lie because `{ bears: number }` is still a subtype of `{ bears Note that we don't use the curried version when using `combine` because `combine` "creates" the state. When using a middleware that creates the state, it isn't necessary to use the curried version because the state now can be inferred. Another middleware that creates state is `redux`. So when using `combine`, `redux`, or any other custom middleware that creates the state, we don't recommend using the curried version. +If you want to infer state type also outside of state declaration, you can use the `ExtractState` type helper: + +```ts +import { create, ExtractState } from 'zustand' +import { combine } from 'zustand/middleware' + +type BearState = ExtractState + +const useBearStore = create( + combine({ bears: 0 }, (set) => ({ + increase: (by: number) => set((state) => ({ bears: state.bears + by })), + })), +) +``` + ## Using middlewares You do not have to do anything special to use middlewares in TypeScript. diff --git a/src/react.ts b/src/react.ts index a8a58cfe22..31baccbd1a 100644 --- a/src/react.ts +++ b/src/react.ts @@ -1,14 +1,13 @@ import React from 'react' import { createStore } from './vanilla.ts' import type { + ExtractState, Mutate, StateCreator, StoreApi, StoreMutatorIdentifier, } from './vanilla.ts' -type ExtractState = S extends { getState: () => infer T } ? T : never - type ReadonlyStoreApi = Pick< StoreApi, 'getState' | 'getInitialState' | 'subscribe' diff --git a/src/vanilla.ts b/src/vanilla.ts index 656d640620..a20f0f8ca5 100644 --- a/src/vanilla.ts +++ b/src/vanilla.ts @@ -13,6 +13,8 @@ export interface StoreApi { subscribe: (listener: (state: T, prevState: T) => void) => () => void } +export type ExtractState = S extends { getState: () => infer T } ? T : never + type Get = K extends keyof T ? T[K] : F export type Mutate = number extends Ms['length' & keyof Ms]