store.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { ModuleRoot } from "moduse";
  2. import { computed, reactive } from "vue";
  3. import {
  4. AnyFun,
  5. ClassType,
  6. EmptyObj,
  7. ObjType,
  8. UnionToIntersectionReturnType,
  9. UnionToIntersectionType
  10. } from "../../typing";
  11. type IStore = {
  12. state: () => any;
  13. getters?: any;
  14. actions?: any;
  15. };
  16. interface IDefineStore {
  17. <
  18. K extends ClassType<any>,
  19. State extends () => ObjType<any>,
  20. Getters extends ObjType<(state: ReturnType<State>) => any>,
  21. Actions extends ObjType<AnyFun>
  22. >(
  23. this: K,
  24. store: {
  25. state: State;
  26. getters: Getters & ThisType<InstanceType<K>>;
  27. actions: Actions & ThisType<InstanceType<K>>;
  28. }
  29. ): {
  30. state: State;
  31. getters: Getters;
  32. actions: Actions;
  33. };
  34. <
  35. K extends ClassType<any>,
  36. State extends () => ObjType<any>,
  37. Actions extends ObjType<AnyFun>
  38. >(
  39. this: K,
  40. store: {
  41. state: State;
  42. actions: Actions & ThisType<InstanceType<K>>;
  43. }
  44. ): {
  45. state: State;
  46. getters: EmptyObj;
  47. actions: Actions;
  48. };
  49. <
  50. K extends ClassType<any>,
  51. State extends () => ObjType<any>,
  52. Getters extends ObjType<(state: ReturnType<State>) => any>
  53. >(
  54. this: K,
  55. store: {
  56. state: State;
  57. getters: Getters & ThisType<InstanceType<K>>;
  58. }
  59. ): {
  60. state: State;
  61. getters: Getters;
  62. actions: EmptyObj;
  63. };
  64. <K extends ClassType<any>, State extends () => ObjType<any>>(
  65. this: K,
  66. store: {
  67. state: State;
  68. }
  69. ): {
  70. state: State;
  71. getters: EmptyObj;
  72. actions: EmptyObj;
  73. };
  74. }
  75. export const defineStore: IDefineStore = function (store: any) {
  76. return store;
  77. };
  78. export function useStore<T extends IStore>(
  79. this: ModuleRoot,
  80. store: T | T[]
  81. ): UnionToIntersectionType<ReturnType<T["state"]>, never> &
  82. UnionToIntersectionReturnType<T["getters"], never> &
  83. UnionToIntersectionType<T["actions"], never> {
  84. const data: any = {},
  85. actions: any = {};
  86. const stores = store instanceof Array ? store : [store];
  87. stores.forEach((store) => {
  88. Object.assign(data, store.state());
  89. if (store.getters) {
  90. Object.entries(store.getters).forEach(([key, value]) => {
  91. data[key] = computed(() => (value as any).call(this, state));
  92. });
  93. }
  94. if (store.actions) {
  95. Object.entries(store.actions).forEach(([key, value]) => {
  96. actions[key] = (value as any).bind(this);
  97. });
  98. }
  99. });
  100. const state = reactive(data);
  101. Object.setPrototypeOf(state, actions);
  102. return state;
  103. }