import {
+ ComputedRef,
isReactive,
isRef,
isVue2,
+ Ref,
toRaw,
+ ToRef,
toRef,
ToRefs,
toRefs,
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
*/
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) {
} 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)) {
_ActionsTree,
storeToRefs,
} from './'
-import { App, ref, Ref } from 'vue'
+import { App, computed, ComputedRef, ref, Ref } from 'vue'
declare module '../dist/pinia' {
export interface MapStoresCustomization {
expectType<{
n: Ref<number>
- double: Ref<number>
+ double: ComputedRef<number>
myState: Ref<number>
stateOnly: Ref<number>
}>(
})()
)
)
+
+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
+ }
+ })()
+ )
+)