注:zustand版本
4.5.2
一、没有中间情况
基本用法
注:例子1
import { create } from 'zustand';
interface BearState {
bears: number;
increase: (by: number) => void;
}
export const useBearStore = create<BearState>((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}));
类型解析
type CreateStore = {
// 第一个函数重载
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): Mutate<StoreApi<T>, Mos>;
// 第二个函数重载
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => Mutate<StoreApi<T>, Mos>;
};
注:命中第一个函数重载的。
StateCreator
export type StateCreator<T, Mis extends [StoreMutatorIdentifier, unknown][] = [], Mos extends [StoreMutatorIdentifier, unknown][] = [], U = T> = ((setState: Get<Mutate<StoreApi<T>, Mis>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, Mis>, 'getState', never>, store: Mutate<StoreApi<T>, Mis>) => U) & {
$$storeMutators?: Mos;
};
因为Mis类型为[],StateCreator类型即为
export type StateCreator<T, [], Mos extends [StoreMutatorIdentifier, unknown][] = [], U = T> = ((setState: Get<Mutate<StoreApi<T>, []>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, []>, 'getState', never>, store: Mutate<StoreApi<T>, []>) => U) & {
$$storeMutators?: Mos;
};
Mos类型被推断为[],StateCreator类型即为
export type StateCreator<T, [], [], U = T> = ((setState: Get<Mutate<StoreApi<T>, []>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, []>, 'getState', never>, store: Mutate<StoreApi<T>, []>) => U) & {
$$storeMutators?: [];
};
StoreApi类型
export interface StoreApi<T> {
setState: SetStateInternal<T>;
getState: () => T;
getInitialState: () => T;
subscribe: (listener: (state: T, prevState: T) => void) => () => void;
/**
* @deprecated Use `unsubscribe` returned by `subscribe`
*/
destroy: () => void;
}
SetStateInternal
注:比较简单,不作展开
type SetStateInternal<T> = {
_(partial: T | Partial<T> | {
_(state: T): T | Partial<T>;
}['_'], replace?: boolean | undefined): void;
}['_'];
Mutate
export type Mutate<S, Ms> = number extends Ms['length' & keyof Ms] ? S : Ms extends [] ? S : Ms extends [[infer Mi, infer Ma], ...infer Mrs] ? Mutate<StoreMutators<S, Ma>[Mi & StoreMutatorIdentifier], Mrs> : never;
由上面类型推断,Ms类型为
[],keyof[]有length属性;则'length' & keyof Ms等于'length';数组的length属性类型为number;因此返回S,即BearState。
Get
获取对象某个属性值
type Get<T, K, F> = K extends keyof T ? T[K] : F;
UseBoundStore
export type UseBoundStore<S extends WithReact<ReadonlyStoreApi<unknown>>> = {
// ExtractState:指定getState
(): ExtractState<S>
<U>(selector: (state: ExtractState<S>) => U): U
/**
* @deprecated Use `createWithEqualityFn` from 'zustand/traditional'
*/
<U>(
selector: (state: ExtractState<S>) => U,
equalityFn: (a: U, b: U) => boolean,
): U
} & S
ExtractState
type ExtractState<S> = S extends { getState: () => infer T } ? T : never
没有中间情况,zustand推荐写法
注:例子2;和例子1区别是使用柯里化调用
()(...)。Ms类型推断为[],类型同例子1
import { create } from 'zustand';
interface BearState {
bears: number;
increase: (by: number) => void;
}
export const useBearStore = create<BearState>()((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
}));
有中间件情况
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface BearState {
bears: number;
increase: (by: number) => void;
}
export const useBearStore = create<BearState>()(
immer((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
})),
);
类型解析
type CreateStore = {
// 第一个函数重载
<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>): Mutate<StoreApi<T>, Mos>;
// 第二个函数重载
<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [], Mos>) => Mutate<StoreApi<T>, Mos>;
};
注:命中第二个函数重载的。
immer
注:immer类型推断如下
Immer类型定义
type Immer = <T, Mps extends [StoreMutatorIdentifier, unknown][] = [], Mcs extends [StoreMutatorIdentifier, unknown][] = []>(initializer: StateCreator<T, [...Mps, ['zustand/immer', never]], Mcs>) => StateCreator<T, Mps, [['zustand/immer', never], ...Mcs]>;
只有immer一个中间件时
Mps类型为[],Mcs类型为[]
简化后,如下
type Immer = <T, [], []>(initializer: StateCreator<T, [...[], ['zustand/immer', never]], []>) => StateCreator<T, [], [['zustand/immer', never], ...[]]>;
省略拓展运算符后如下
type Immer = <T, [], []>(initializer: StateCreator<T, [['zustand/immer', never]], []>) => StateCreator<T, [], [['zustand/immer', never]]>;
StateCreator
export type StateCreator<T, Mis extends [StoreMutatorIdentifier, unknown][] = [], Mos extends [StoreMutatorIdentifier, unknown][] = [], U = T> = ((setState: Get<Mutate<StoreApi<T>, Mis>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, Mis>, 'getState', never>, store: Mutate<StoreApi<T>, Mis>) => U) & {
$$storeMutators?: Mos;
};
因为Mis类型为[['zustand/immer', never]],StateCreator类型即为
export type StateCreator<T, [['zustand/immer', never]], Mos extends [StoreMutatorIdentifier, unknown][] = [], U = T> = ((setState: Get<Mutate<StoreApi<T>, [['zustand/immer', never]]>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, [['zustand/immer', never]]>, 'getState', never>, store: Mutate<StoreApi<T>, [['zustand/immer', never]]>) => U) & {
$$storeMutators?: Mos;
};
Mos类型被推断为[],StateCreator类型即为
export type StateCreator<T, [['zustand/immer', never]], [], U = T> = ((setState: Get<Mutate<StoreApi<T>, [['zustand/immer', never]]>, 'setState', never>, getState: Get<Mutate<StoreApi<T>, [['zustand/immer', never]]>, 'getState', never>, store: Mutate<StoreApi<T>, [['zustand/immer', never]]>) => U) & {
$$storeMutators?: [];
};
Mutate
export type Mutate<S, Ms> = number extends Ms['length' & keyof Ms] ? S : Ms extends [] ? S : Ms extends [[infer Mi, infer Ma], ...infer Mrs] ? Mutate<StoreMutators<S, Ma>[Mi & StoreMutatorIdentifier], Mrs> : never;
注:这里
keyof[['zustand/immer', never]]为与[]同类型,包含length属性;Ms['length']则返回1,因为只有一个中间件(即数组长度为1),因此走下面逻辑。Ma类型为never。
Mutate<StoreMutators<S, never>[Mi & StoreMutatorIdentifier], []>
StoreMutators
注:immer中间件重写了
StoreMutators类型
declare module '../vanilla' {
// 重写了StoreMutators接口类型
interface StoreMutators<S, A> {
['zustand/immer']: WithImmer<S>;
}
}
// Immer类型覆盖Store原有类型
type Write<T, U> = Omit<T, keyof U> & U;
type SkipTwo<T> = T extends {
length: 0;
} ? [] : T extends {
length: 1;
} ? [] : T extends {
length: 0 | 1;
} ? [] : T extends [unknown, unknown, ...infer A] ? A : T extends [unknown, unknown?, ...infer A] ? A : T extends [unknown?, unknown?, ...infer A] ? A : never;
type WithImmer<S> = Write<S, StoreImmer<S>>;
// ...a支持更多参数,SKipTwo是忽略前面参数;目前zustand只支持partial, replace这两个参数
type StoreImmer<S> = S extends {
getState: () => infer T;
setState: infer SetState;
} ? SetState extends (...a: infer A) => infer Sr ? {
setState(nextStateOrUpdater: T | Partial<T> | ((state: Draft<T>) => void), shouldReplace?: boolean | undefined, ...a: SkipTwo<A>): Sr;
} : never : never;
多个中间件使用
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
import { persist, createJSONStorage } from 'zustand/middleware';
interface BearState {
bears: number;
increase: (by: number) => void;
}
export const useBearStore = create<BearState>()(
persist(
immer((set) => ({
bears: 0,
increase: (by) => set((state) => ({ bears: state.bears + by })),
})),
{
name: 'food-storage', // name of the item in the storage (must be unique)
storage: createJSONStorage(() => sessionStorage), // (optional) by default, 'localStorage' is used
},
),
);
不同地方只有 Mutate
export type Mutate<S, Ms> = number extends Ms['length' & keyof Ms] ? S : Ms extends [] ? S : Ms extends [[infer Mi, infer Ma], ...infer Mrs] ? Mutate<StoreMutators<S, Ma>[Mi & StoreMutatorIdentifier], Mrs> : never;
注:这里是递归整合中间件新增属性 注:这里
keyof[['zustand/immer', never]]为与[]同类型,包含length属性;Ms['length']则返回2,因为有两个中间件,因此走下面逻辑。Ma类型为never。