]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
refactor: Revert "refactor: Revert "fix(types): fix storeToRefs state return type...
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 16 Apr 2024 15:55:06 +0000 (17:55 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 16 Apr 2024 15:55:06 +0000 (17:55 +0200)
This reverts commit f550c6080514a851f77a652becbf5b90818479d1.

packages/pinia/src/storeToRefs.ts
packages/pinia/test-dts/customizations.test-d.ts

index 76e91c333b3aa426d2ae22ce77b56e92c03acc6c..a6b91217e264aae4e10a5e3bae523525b230cf06 100644 (file)
@@ -11,7 +11,15 @@ import {
   toRefs,
 } from 'vue-demi'
 import { StoreGetters, StoreState } from './store'
-import type { PiniaCustomStateProperties, StoreGeneric } from './types'
+import type {
+  _ActionsTree,
+  _GettersTree,
+  _UnwrapAll,
+  PiniaCustomStateProperties,
+  StateTree,
+  Store,
+  StoreGeneric,
+} from './types'
 
 type ToComputedRefs<T> = {
   [K in keyof T]: ToRef<T[K]> extends Ref<infer U>
@@ -19,13 +27,31 @@ type ToComputedRefs<T> = {
     : ToRef<T[K]>
 }
 
+/**
+ * Extracts the refs of a state object from a store. If the state value is a Ref or type that extends ref, it will be kept as is.
+ * Otherwise, it will be converted into a Ref.
+ * @internal
+ */
+type ToStateRefs<SS> =
+  SS extends Store<
+    string,
+    infer UnwrappedState,
+    _GettersTree<StateTree>,
+    _ActionsTree
+  >
+    ? UnwrappedState extends _UnwrapAll<Pick<infer State, infer Key>>
+      ? {
+          [K in Key]: ToRef<State[K]>
+        }
+      : ToRefs<UnwrappedState>
+    : ToRefs<StoreState<SS>>
+
 /**
  * Extracts the return type for `storeToRefs`.
  * Will convert any `getters` into `ComputedRef`.
  */
-export type StoreToRefs<SS extends StoreGeneric> = ToRefs<
-  StoreState<SS> & PiniaCustomStateProperties<StoreState<SS>>
-> &
+export type StoreToRefs<SS extends StoreGeneric> = ToStateRefs<SS> &
+  ToRefs<PiniaCustomStateProperties<StoreState<SS>>> &
   ToComputedRefs<StoreGetters<SS>>
 
 /**
index b937c989a2276bcc76dc31de3d13ed4d46ad512b..54bd5b303386dd071f7b0a7e5238bff2f218c2e5 100644 (file)
@@ -193,3 +193,76 @@ expectType<{
     })()
   )
 )
+
+expectType<{
+  n: Ref<number>
+  customN: Ref<number> & { plusOne: () => void }
+  double: ComputedRef<number>
+  myState: Ref<number>
+  stateOnly: Ref<number>
+}>(
+  storeToRefs(
+    defineStore('a', () => {
+      const n = ref(1)
+      const customN = ref(1) as Ref<number> & { plusOne: () => void }
+      const double = computed(() => n.value * 2)
+      return {
+        n,
+        customN,
+        double,
+      }
+    })()
+  )
+)
+
+expectType<{
+  n: Ref<number>
+  customN: Ref<number> & { plusOne: () => void }
+  double: ComputedRef<number>
+  myState: Ref<number>
+  stateOnly: Ref<number>
+}>(
+  storeToRefs(
+    defineStore('a', () => {
+      const n = ref(1)
+      const customN = ref(1) as Ref<number> & { plusOne: () => void }
+      const double = computed(() => n.value * 2)
+
+      function plusOne() {
+        customN.value++
+      }
+
+      return {
+        n,
+        customN,
+        double,
+        plusOne,
+      }
+    })()
+  )
+)
+
+expectType<{
+  n: Ref<number>
+  customN: Ref<number> & { plusOne: () => void }
+  double: ComputedRef<number>
+  myState: Ref<number>
+  stateOnly: Ref<number>
+}>(
+  storeToRefs(
+    defineStore('a', {
+      state: () => ({
+        n: 1,
+        customN: ref(1) as Ref<number> & { plusOne: () => void },
+      }),
+      getters: {
+        double: (state) => state.n * 2,
+      },
+      actions: {
+        plusOne() {
+          this.n++
+        },
+      },
+    })()
+  )
+)