mpstore-next
Version:
一个轻量级的状态管理库,类似于`pinia`、`vuex`,适用于微信小程序。
297 lines (293 loc) • 10 kB
TypeScript
type AnyObject = WechatMiniprogram.IAnyObject;
/**
* 微信小程序页面实例
*/
type PageInstance = WechatMiniprogram.Page.Instance<WithStore<WechatMiniprogram.Page.DataOption, AnyObject>, WechatMiniprogram.Page.CustomOption>;
/**
* 微信小程序组件实例
*/
type ComponentInstance = WechatMiniprogram.Component.Instance<WithStore<WechatMiniprogram.Component.DataOption, AnyObject>, WechatMiniprogram.Component.PropertyOption, WechatMiniprogram.Component.MethodOption, WechatMiniprogram.IAnyObject>;
/**
* 定义一个可选的 Store 配置对象,包含 `stores` 字段。
* `stores` 字段为部分 Store 配置,用于动态定义多个模块化的 store。
*
* @template S - 状态类型。
* @template G - 派生状态类型(Getters)。
* @template A - 行为类型(Actions)。
*/
type TStore<S extends State = State, G extends Getters<S> = Getters<S>, A extends Actions = Actions> = Partial<{
stores: Partial<StoreConfig<S, G, A>>;
}>;
/**
* 用于扩展组件或数据对象,使其具备与 store 交互的能力。
* 可以访问当前模块或多个模块的 `$state` 和 `$getter`。
*
* @template TData - 原始数据类型。
* @template TStoreState - store 状态类型(可同时表示 state 和 getter)。
*/
type WithStore<TData, TStoreState> = TData & Partial<{
/**
* 当前默认 store 的状态。
*/
$state: TStoreState;
/**
* 当前默认 store 的 getter。
*/
$getter: TStoreState;
}> & Partial<{
/**
* 支持多个命名空间 store,每个 store 可以拥有自己的 `$state` 和 `$getter`。
*/
[key: string]: Partial<{
$state: TStoreState;
$getter: TStoreState;
}>;
}>;
/**
* 配置一个单独的 Store 的结构类型。
*
* @template S - 状态对象的类型(State)
* @template G - Getter 的类型
* @template A - Action 的类型
*/
type OneStoreConfig<S, G, A> = Partial<{
/**
* 需要使用的 store 实例。
*/
store: Store<S, G, A>;
/**
* 过滤store属性,默认为不过滤
*
* 用于按需导入需要的store数据, 只包含`state` 和 `getter`中属性
*/
useProp: string[];
}>;
/**
* 多个 Store 或单个 Store 的完整配置类型。
*
* @template S - 状态对象的类型(State)
* @template G - Getter 的类型
* @template A - Action 的类型
*/
type StoreConfig<S, G, A> = {
/**
* 开始命名空间的隔离
*
* 适用于多个store同时使用,`usePart` 为 `true` 的时候,会使用`defineStore`所定义的`key`作为命名空间的隔离
*/
usePart: boolean;
/**
* 过滤store属性,默认为不过滤
*
* 用于按需导入需要的store数据, 只包含`state` 和 `getter`中属性
*/
useProp: string[];
/**
* 需要使用的 store,可以是单个 Store 实例,也可以是多个 Store 组成的数组。
*/
store: Store<S, G, A> | Array<Store<S, G, A>>;
/**
* 多个store的配置项
*
* 这个时候只会使用`config`,而`store`会被忽略
* 针对每个 store 的单独配置项数组。
* 每项可配置具体的 store 和其对应的使用属性。
*/
config: Array<OneStoreConfig<S, G, A>>;
};
type State = AnyObject;
type Subscriber = (state: AnyObject) => void;
type DeepReadonly<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;
};
type ExtractGetters<G> = {
readonly [K in keyof G as G[K] extends (...args: any[]) => infer R ? R extends void ? never : K : never]: G[K] extends (...args: any[]) => infer R ? R : never;
};
type Getters<S> = {
[K in string]: (state: DeepReadonly<S>) => unknown;
};
type Actions = {
[K in string]: (...args: any[]) => unknown;
};
type Store<S, G, A> = S & Omit<ExtractGetters<G>, keyof S> & Readonly<A & StoreAction<S, G, A>>;
type IsFunction<T> = T extends (...args: any[]) => any ? true : false;
type WatchProperty<T> = IsFunction<T> extends true ? never : T;
type WatchValue<T> = WatchProperty<T> | WatchProperty<T>[];
/**
* 定义 store 的选项类型。
*
* @template S 状态对象类型
* @template G getter 对象类型
* @template A action 对象类型
*/
type DefineStoreOptions<S extends State, G extends Getters<S>, A extends Actions> = {
/**
* 返回状态对象的函数。
*/
state: () => S;
/**
* getter 对象,可通过 `this` 访问状态、getter(排除状态键)和 actions。
*/
getters?: G & ThisType<S & Omit<ExtractGetters<G>, keyof S> & A>;
/**
* action 对象,可通过 `this` 访问状态、getter(排除状态键)和 actions。
*/
actions?: A & ThisType<S & Omit<ExtractGetters<G>, keyof S> & A>;
};
/**
* 每个 Store 实例额外扩展的方法集合。
*
* @template S 状态类型
* @template G getter 类型
* @template A action 类型
*/
type StoreAction<S, G, A> = {
/**
* 获取当前 store 的唯一 key。
*/
$key: () => string;
/**
* 批量更新状态。
* @param partial 状态的部分字段
*/
$patch: (partial: Partial<S>) => void;
/**
* 订阅状态变更。
* @param fn 回调函数
* @returns 取消订阅函数,返回值标记是否成功取消
*/
$subscribe: (fn: Subscriber) => () => boolean;
/**
* 绑定状态更新逻辑,支持局部更新。
* @param fn 更新函数
* @param part 是否为局部绑定
* @returns 取消更新函数
*/
$update: (fn: Subscriber, part?: boolean) => () => boolean;
/**
* 判断某个实例是否已绑定。
* @param instance 页面或组件实例
*/
$has: (instance: PageInstance | ComponentInstance) => boolean;
/**
* 将状态绑定到页面或组件实例。
* @param instance 页面或组件实例
* @param part 是否局部绑定
* @param filterProps 可选字段过滤列表
*/
$bind: (instance: PageInstance | ComponentInstance, part?: boolean, filterProps?: string[]) => void;
/**
* 解绑页面或组件实例。
* @param instance 页面或组件实例
*/
$unbind: (instance: PageInstance | ComponentInstance) => void;
/**
* 销毁该 store 实例。
*/
$dispose: () => void;
/**
* 重置为初始状态。
*/
$reset: () => void;
/**
* 监听某个值的变化。
*
* @template T 要监听的字段的类型
* @param source 返回要监听的值的函数
* @param cb 值变化时的回调
* @param options 配置项(是否立即触发)
* @returns 停止监听的函数
*/
$watch: <T = Store<S, G, A>[Exclude<keyof Store<S, G, A>, keyof (A & StoreAction<S, G, A>)>]>(source: () => WatchValue<T>, cb: (newValue: WatchValue<T>, oldValue: WatchValue<T>) => void, options?: {
immediate?: boolean;
}) => () => void;
};
/**
* 定义一个小程序组件。
*
* @template TData 组件数据类型
* @template TProperty 组件属性类型
* @template TMethod 组件方法类型
* @template TCustomInstanceProperty 自定义实例属性类型
* @template TIsPage 是否是页面(默认 false)
* @param options 组件配置项,支持扩展 store
* @returns 微信小程序组件实例
*
* @example
* ```javascript
* const counterStore = useCounterStore()
* defineComponent({
* stores: {
* store: counterStore
* },
* data: {
* },
* methods: {
* }
* })
* ```
*/
declare function defineComponent<TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption, TCustomInstanceProperty extends WechatMiniprogram.IAnyObject = {}, TIsPage extends boolean = false>(options: WechatMiniprogram.Component.Options<TData, TProperty, TMethod, TCustomInstanceProperty, TIsPage> & TStore): string;
/**
* 定义一个小程序页面。
*
* @template TData 页面数据类型
* @template TCustom 自定义页面选项类型
* @param options 页面配置项,支持扩展 store
* @returns 微信小程序页面实例
*
* @example
* ```javascript
* const counterStore = useCounterStore()
* definePage({
* stores: {
* store: counterStore
* },
* data: {
* },
* })
* ```
*/
declare function definePage<TData extends WechatMiniprogram.Page.DataOption, TCustom extends WechatMiniprogram.Page.CustomOption>(options: WechatMiniprogram.Page.Options<TData, TCustom> & TStore): void;
/**
* 定义一个新的 Store。
*
* 用于创建响应式状态管理对象,支持 state、getters 和 actions,
* 并提供一套生命周期管理函数(如 `$patch`, `$subscribe`, `$watch`,`$update` 等)。
*
* @template S Store 的状态类型(State)
* @template G Store 的 getter 类型(Getters)
* @template A Store 的 action 类型(Actions)
*
* @param key - Store 的唯一标识符,通常用于内部存储和调试。
* @param options - 包含 `state`、`getters` 和 `actions` 的配置对象:
* - `state`: 返回初始状态的函数。
* - `getters`: 可选的 getter 对象,用于派生状态。
* - `actions`: 可选的 action 对象,用于封装业务逻辑。
*
* @returns 返回一个函数,调用该函数可获取该 Store 实例对象。
* Store 实例具备完整的状态读写、监听和绑定功能。
*
* @example
* ```javascript
* const useCounterStore = defineStore('counter', {
* state: () => ({ count: 0 }),
* getters: {
* double() {
* return this.count * 2;
* }
* },
* actions: {
* increment() {
* this.count++;
* }
* }
* });
*
* const counter = useCounterStore();
* counter.increment();
* console.log(counter.double); // 输出:2
* ```
*/
declare function defineStore<S extends State, G extends Getters<S>, A extends Actions>(key: string, options: DefineStoreOptions<S, G, A>): () => Store<S, G, A>;
export { defineComponent, definePage, defineStore };