Skip to content

Commit

Permalink
fix!: switch compute to first arg for proper type interpolation, Read…
Browse files Browse the repository at this point in the history
…only<T> type
  • Loading branch information
chrisvander committed Mar 3, 2024
1 parent 04089ff commit 72e064f
Showing 1 changed file with 10 additions and 12 deletions.
22 changes: 10 additions & 12 deletions src/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,35 @@ export type ComputedStateCreator = <
Mps extends [StoreMutatorIdentifier, unknown][] = [],
Mcs extends [StoreMutatorIdentifier, unknown][] = [],
>(
compute: (state: T) => A,
f: StateCreator<T, [...Mps, ["chrisvander/zustand-computed", A]], Mcs>,
opts?: ComputedStateOpts<T>,
) => StateCreator<T, Mps, [["chrisvander/zustand-computed", A], ...Mcs], T>

type ComputedStateImpl = <T extends object, A extends object>(
compute: (state: T) => A,
f: StateCreator<T, [], []>,
opts?: ComputedStateOpts<T>,
) => StateCreator<T, Mps, [["chrisvander/zustand-computed", A], ...Mcs], T & A>
) => StateCreator<T, [], [], T>

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">
? Omit<StoreApi<T & Readonly<A>>, "setState" | "getInitialState">
: never
type WithCompute<S, A> = Write<S, StoreCompute<S, A>>

declare module "zustand" {
interface StoreMutators<S, A> {
"chrisvander/zustand-computed": WithCompute<Cast<S, object>, A>
"chrisvander/zustand-computed": Write<S, StoreCompute<S, A>>
}
}

type ComputedStateImpl = <T extends object, A extends object>(
f: StateCreator<T, [], []>,
compute: (state: T) => A,
opts?: ComputedStateOpts<T>,
) => StateCreator<T, [], [], T & A>

type SetStateWithArgs = Parameters<ReturnType<ComputedStateImpl>>[0] extends (...args: infer U) => void
? (...args: [...U, ...unknown[]]) => void
: never

const computedImpl: ComputedStateImpl = (f, compute, opts) => {
const computedImpl: ComputedStateImpl = (compute, f, opts) => {
// set of keys that have been accessed in any compute call
const trackedSelectors = new Set<string | number | symbol>()
return (set, get, api) => {
Expand Down

0 comments on commit 72e064f

Please sign in to comment.