]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
fix(types): type storeToRefs getters as ComputedRef (#1898)
authorBen Jones <bensheltonjones@gmail.com>
Wed, 28 Dec 2022 21:21:55 +0000 (21:21 +0000)
committerGitHub <noreply@github.com>
Wed, 28 Dec 2022 21:21:55 +0000 (22:21 +0100)
Closes https://github.com/vuejs/pinia/issues/1852

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

index fc294d31f94c3ae8e73e6241f58cae58f04a8297..76e91c333b3aa426d2ae22ce77b56e92c03acc6c 100644 (file)
@@ -1,8 +1,11 @@
 import {
+  ComputedRef,
   isReactive,
   isRef,
   isVue2,
+  Ref,
   toRaw,
+  ToRef,
   toRef,
   ToRefs,
   toRefs,
@@ -10,6 +13,21 @@ import {
 import { StoreGetters, StoreState } from './store'
 import type { PiniaCustomStateProperties, StoreGeneric } from './types'
 
+type ToComputedRefs<T> = {
+  [K in keyof T]: ToRef<T[K]> extends Ref<infer U>
+    ? ComputedRef<U>
+    : ToRef<T[K]>
+}
+
+/**
+ * Extracts the return type for `storeToRefs`.
+ * Will convert any `getters` into `ComputedRef`.
+ */
+export type StoreToRefs<SS extends StoreGeneric> = ToRefs<
+  StoreState<SS> & PiniaCustomStateProperties<StoreState<SS>>
+> &
+  ToComputedRefs<StoreGetters<SS>>
+
 /**
  * Creates an object of references with all the state, getters, and plugin-added
  * state properties of the store. Similar to `toRefs()` but specifically
@@ -20,9 +38,7 @@ import type { PiniaCustomStateProperties, StoreGeneric } from './types'
  */
 export function storeToRefs<SS extends StoreGeneric>(
   store: SS
-): ToRefs<
-  StoreState<SS> & StoreGetters<SS> & PiniaCustomStateProperties<StoreState<SS>>
-> {
+): StoreToRefs<SS> {
   // See https://github.com/vuejs/pinia/issues/852
   // It's easier to just use toRefs() even if it includes more stuff
   if (isVue2) {
@@ -31,11 +47,7 @@ export function storeToRefs<SS extends StoreGeneric>(
   } else {
     store = toRaw(store)
 
-    const refs = {} as ToRefs<
-      StoreState<SS> &
-        StoreGetters<SS> &
-        PiniaCustomStateProperties<StoreState<SS>>
-    >
+    const refs = {} as StoreToRefs<SS>
     for (const key in store) {
       const value = store[key]
       if (isRef(value) || isReactive(value)) {
index bab6afe1544a9f9e3878363e8c7d3074166db765..ebf3b6435ec421ebe0077b4d9fdf3c5b54b12c81 100644 (file)
@@ -6,7 +6,7 @@ import {
   _ActionsTree,
   storeToRefs,
 } from './'
-import { App, ref, Ref } from 'vue'
+import { App, computed, ComputedRef, ref, Ref } from 'vue'
 
 declare module '../dist/pinia' {
   export interface MapStoresCustomization {
@@ -159,7 +159,7 @@ expectType<{ a: Ref<boolean>; myState: Ref<number>; stateOnly: Ref<number> }>(
 
 expectType<{
   n: Ref<number>
-  double: Ref<number>
+  double: ComputedRef<number>
   myState: Ref<number>
   stateOnly: Ref<number>
 }>(
@@ -172,3 +172,21 @@ expectType<{
     })()
   )
 )
+
+expectType<{
+  n: Ref<number>
+  double: ComputedRef<number>
+  myState: Ref<number>
+  stateOnly: Ref<number>
+}>(
+  storeToRefs(
+    defineStore('a', () => {
+      const n = ref(1)
+      const double = computed(() => n.value * 2)
+      return {
+        n,
+        double
+      }
+    })()
+  )
+)