mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
fix(types): fix StateCreator subtyping (#1373)
* fix(types): fix `StateCreator` subtyping * prefer import type Co-authored-by: daishi <daishi@axlight.com>
This commit is contained in:
parent
b36f29af30
commit
ca059788d3
@ -246,9 +246,9 @@ type Logger = <
|
||||
) => StateCreator<T, Mps, Mcs>
|
||||
|
||||
type LoggerImpl = <T extends State>(
|
||||
f: PopArgument<StateCreator<T, [], []>>,
|
||||
f: StateCreator<T, [], []>,
|
||||
name?: string
|
||||
) => PopArgument<StateCreator<T, [], []>>
|
||||
) => StateCreator<T, [], []>
|
||||
|
||||
const loggerImpl: LoggerImpl = (f, name) => (set, get, store) => {
|
||||
type T = ReturnType<typeof f>
|
||||
@ -263,12 +263,6 @@ const loggerImpl: LoggerImpl = (f, name) => (set, get, store) => {
|
||||
|
||||
export const logger = loggerImpl as unknown as Logger
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
|
||||
// ---
|
||||
|
||||
const useBearStore = create<BearState>()(
|
||||
@ -310,9 +304,9 @@ declare module 'zustand' {
|
||||
}
|
||||
|
||||
type FooImpl = <T extends State, A>(
|
||||
f: PopArgument<StateCreator<T, [], []>>,
|
||||
f: StateCreator<T, [], []>,
|
||||
bar: A
|
||||
) => PopArgument<StateCreator<T, [], []>>
|
||||
) => StateCreator<T, [], []>
|
||||
|
||||
const fooImpl: FooImpl = (f, bar) => (set, get, _store) => {
|
||||
type T = ReturnType<typeof f>
|
||||
@ -325,12 +319,6 @@ const fooImpl: FooImpl = (f, bar) => (set, get, _store) => {
|
||||
|
||||
export const foo = fooImpl as unknown as Foo
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
|
||||
type Write<T extends object, U extends object> = Omit<T, keyof U> & U
|
||||
|
||||
type Cast<T, U> = T extends U ? T : U
|
||||
|
||||
@ -141,15 +141,9 @@ declare module '../vanilla' {
|
||||
}
|
||||
|
||||
type DevtoolsImpl = <T>(
|
||||
storeInitializer: PopArgument<StateCreator<T, [], []>>,
|
||||
storeInitializer: StateCreator<T, [], []>,
|
||||
devtoolsOptions?: DevtoolsOptions
|
||||
) => PopArgument<StateCreator<T, [], []>>
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
) => StateCreator<T, [], []>
|
||||
|
||||
export type NamedSet<T> = WithDevtools<StoreApi<T>>['setState']
|
||||
|
||||
|
||||
@ -49,15 +49,9 @@ type StoreImmer<S> = S extends {
|
||||
: never
|
||||
: never
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
|
||||
type ImmerImpl = <T>(
|
||||
storeInitializer: PopArgument<StateCreator<T, [], []>>
|
||||
) => PopArgument<StateCreator<T, [], []>>
|
||||
storeInitializer: StateCreator<T, [], []>
|
||||
) => StateCreator<T, [], []>
|
||||
|
||||
const immerImpl: ImmerImpl = (initializer) => (set, get, store) => {
|
||||
type T = ReturnType<typeof initializer>
|
||||
|
||||
@ -319,14 +319,8 @@ type WithPersist<S, A> = S extends { getState: () => infer T }
|
||||
: never
|
||||
|
||||
type PersistImpl = <T>(
|
||||
storeInitializer: PopArgument<StateCreator<T, [], []>>,
|
||||
storeInitializer: StateCreator<T, [], []>,
|
||||
options: PersistOptions<T, T>
|
||||
) => PopArgument<StateCreator<T, [], []>>
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
) => StateCreator<T, [], []>
|
||||
|
||||
export const persist = persistImpl as unknown as Persist
|
||||
|
||||
@ -31,16 +31,10 @@ declare module '../vanilla' {
|
||||
}
|
||||
}
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
|
||||
type ReduxImpl = <T, A extends Action>(
|
||||
reducer: (state: T, action: A) => T,
|
||||
initialState: T
|
||||
) => PopArgument<StateCreator<T & ReduxState<A>, [], []>>
|
||||
) => StateCreator<T & ReduxState<A>, [], []>
|
||||
|
||||
const reduxImpl: ReduxImpl = (reducer, initial) => (set, _get, api) => {
|
||||
type S = typeof initial
|
||||
@ -53,4 +47,4 @@ const reduxImpl: ReduxImpl = (reducer, initial) => (set, _get, api) => {
|
||||
|
||||
return { dispatch: (...a) => (api as any).dispatch(...a), ...initial }
|
||||
}
|
||||
export const redux = reduxImpl as Redux
|
||||
export const redux = reduxImpl as unknown as Redux
|
||||
|
||||
@ -40,14 +40,8 @@ type StoreSubscribeWithSelector<T> = {
|
||||
}
|
||||
|
||||
type SubscribeWithSelectorImpl = <T extends object>(
|
||||
storeInitializer: PopArgument<StateCreator<T, [], []>>
|
||||
) => PopArgument<StateCreator<T, [], []>>
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
storeInitializer: StateCreator<T, [], []>
|
||||
) => StateCreator<T, [], []>
|
||||
|
||||
const subscribeWithSelectorImpl: SubscribeWithSelectorImpl =
|
||||
(fn) => (set, get, api) => {
|
||||
|
||||
@ -30,8 +30,7 @@ export type StateCreator<
|
||||
> = ((
|
||||
setState: Get<Mutate<StoreApi<T>, Mis>, 'setState', never>,
|
||||
getState: Get<Mutate<StoreApi<T>, Mis>, 'getState', never>,
|
||||
store: Mutate<StoreApi<T>, Mis>,
|
||||
$$storeMutations: Mis
|
||||
store: Mutate<StoreApi<T>, Mis>
|
||||
) => U) & { $$storeMutators?: Mos }
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface
|
||||
@ -55,12 +54,6 @@ type CreateStoreImpl = <
|
||||
initializer: StateCreator<T, [], Mos>
|
||||
) => Mutate<StoreApi<T>, Mos>
|
||||
|
||||
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
|
||||
...a: [...infer A, infer _]
|
||||
) => infer R
|
||||
? (...a: A) => R
|
||||
: never
|
||||
|
||||
const createStoreImpl: CreateStoreImpl = (createState) => {
|
||||
type TState = ReturnType<typeof createState>
|
||||
type Listener = (state: TState, prevState: TState) => void
|
||||
@ -94,11 +87,7 @@ const createStoreImpl: CreateStoreImpl = (createState) => {
|
||||
|
||||
const destroy: () => void = () => listeners.clear()
|
||||
const api = { setState, getState, subscribe, destroy }
|
||||
state = (createState as PopArgument<typeof createState>)(
|
||||
setState,
|
||||
getState,
|
||||
api
|
||||
)
|
||||
state = createState(setState, getState, api)
|
||||
return api as any
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import create, {
|
||||
import create from 'zustand'
|
||||
import type {
|
||||
StateCreator,
|
||||
StoreApi,
|
||||
StoreMutatorIdentifier,
|
||||
@ -213,3 +214,22 @@ it('StateCreator<T, [StoreMutatorIdentfier, unknown][]> is StateCreator<T, []>',
|
||||
|
||||
create<State>()(persist(foo()))
|
||||
})
|
||||
|
||||
it('StateCreator subtyping', () => {
|
||||
interface State {
|
||||
count: number
|
||||
increment: () => void
|
||||
}
|
||||
|
||||
const foo: () => StateCreator<State, []> = () => (set, get) => ({
|
||||
count: 0,
|
||||
increment: () => {
|
||||
set({ count: get().count + 1 })
|
||||
},
|
||||
})
|
||||
|
||||
create<State>()(persist(foo()))
|
||||
|
||||
const _testSubtyping: StateCreator<State, [['zustand/persist', unknown]]> =
|
||||
{} as StateCreator<State, []>
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user