import { ModuleRoot } from "moduse"; import { computed, reactive } from "vue"; import { AnyFun, ClassType, EmptyObj, ObjType, UnionToIntersectionReturnType, UnionToIntersectionType } from "../../typing"; type IStore = { state: () => any; getters?: any; actions?: any; }; interface IDefineStore { < K extends ClassType, State extends () => ObjType, Getters extends ObjType<(state: ReturnType) => any>, Actions extends ObjType >( this: K, store: { state: State; getters: Getters & ThisType>; actions: Actions & ThisType>; } ): { state: State; getters: Getters; actions: Actions; }; < K extends ClassType, State extends () => ObjType, Actions extends ObjType >( this: K, store: { state: State; actions: Actions & ThisType>; } ): { state: State; getters: EmptyObj; actions: Actions; }; < K extends ClassType, State extends () => ObjType, Getters extends ObjType<(state: ReturnType) => any> >( this: K, store: { state: State; getters: Getters & ThisType>; } ): { state: State; getters: Getters; actions: EmptyObj; }; , State extends () => ObjType>( this: K, store: { state: State; } ): { state: State; getters: EmptyObj; actions: EmptyObj; }; } export const defineStore: IDefineStore = function (store: any) { return store; }; export function useStore( this: ModuleRoot, store: T | T[] ): UnionToIntersectionType, never> & UnionToIntersectionReturnType & UnionToIntersectionType { const data: any = {}, actions: any = {}; const stores = store instanceof Array ? store : [store]; stores.forEach((store) => { Object.assign(data, store.state()); if (store.getters) { Object.entries(store.getters).forEach(([key, value]) => { data[key] = computed(() => (value as any).call(this, state)); }); } if (store.actions) { Object.entries(store.actions).forEach(([key, value]) => { actions[key] = (value as any).bind(this); }); } }); const state = reactive(data); Object.setPrototypeOf(state, actions); return state; }