zustand-computed
Version:
A Zustand middleware to create computed states.
56 lines (55 loc) • 2.58 kB
TypeScript
import { StateCreator, StoreApi, StoreMutatorIdentifier } from 'zustand';
/**
* Options for when and how your compute function is called.
*/
export type ComputedStateOpts<T> = ({
/**
* An explicit list of keys to track for recomputation. By default,
* `zustand-computed` will run your compute function on any change.
* This lets you filter those keys out. It's better to use the
* `compareFn` to be more explicit about how comparison is determined.
*/
keys?: (keyof T)[];
} | {
/**
* Custom comparison function to determine whether to recompute.
* Receives the previous and next store state, should return true if
* compute should run, false to skip recomputation. This function
* should be *fast* - it determines whether or not you need to
* recompute.
*/
shouldRecompute?: (state: T, nextState: T) => boolean;
}) & {
/**
* @deprecated removed proxy; this does nothing and will be removed.
*/
disableProxy?: boolean;
/**
* Custom equality function for comparing computed values. By default, we use
* `zustand/shallow` to compare each key in your store against the newly-
* computed values. This is likely the desired method of comparison.
*
* The motivation for this function is to ensure that, in the case your
* computed function returns a value that is identical structurally, it
* should not cause a re-render despite the reference being different.
*
* You can disable comparison, so that the most recent result of the
* compute function always triggers downstream re-renders, by simply
* returning false.
*/
equalityFn?: <Y>(a: Y, b: Y) => boolean;
};
export type ComputedStateCreator = <T extends object, A extends object>(compute: (state: T) => A, opts?: ComputedStateOpts<T>) => <Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = [], U = T>(f: StateCreator<T, [...Mps, ["chrisvander/zustand-computed", A]], Mcs>) => StateCreator<T, Mps, [["chrisvander/zustand-computed", A], ...Mcs], U & A>;
type Cast<T, U> = T extends U ? T : U;
type Write<T, U> = Omit<T, keyof U> & U;
type StoreCompute<S, A> = S extends {
getState: () => infer T;
} ? Omit<StoreApi<T & A>, "setState"> : never;
type WithCompute<S, A> = Write<S, StoreCompute<S, A>>;
declare module "zustand/vanilla" {
interface StoreMutators<S, A> {
"chrisvander/zustand-computed": WithCompute<Cast<S, object>, A>;
}
}
export declare const createComputed: ComputedStateCreator;
export {};