diff --git a/packages/pinia/__tests__/mapHelpers.spec.ts b/packages/pinia/__tests__/mapHelpers.spec.ts index 11a5b415f2..6c532857ef 100644 --- a/packages/pinia/__tests__/mapHelpers.spec.ts +++ b/packages/pinia/__tests__/mapHelpers.spec.ts @@ -10,7 +10,7 @@ import { setMapStoreSuffix, } from '../src' import { mount } from '@vue/test-utils' -import { nextTick, defineComponent } from 'vue' +import { nextTick, defineComponent, ref, computed } from 'vue' import { mockWarn } from './vitest-mock-warn' describe('Map Helpers', () => { @@ -245,5 +245,34 @@ describe('Map Helpers', () => { 'replaced replaced' ) }) + + it('setup store', async () => { + const useSetupStore = defineStore('setup', () => { + const a = ref(true) + const n = ref(0) + + const double = computed({ + get: () => n.value + n.value, + set: (v) => { + n.value = v + }, + }) + const notA = computed({ + get: () => !a.value, + set: (v) => { + a.value = v + }, + }) + + return { a, n, double, notA } + }) + + await testComponent( + mapWritableState(useSetupStore, ['n', 'a', 'double', 'notA']), + `{{ n }} {{ a }} {{ double }} {{ notA }}`, + `0 true 0 false`, + 'replaced replaced replacedreplaced false' + ) + }) }) }) diff --git a/packages/pinia/src/types.ts b/packages/pinia/src/types.ts index 4ca20da9e3..017eca6af4 100644 --- a/packages/pinia/src/types.ts +++ b/packages/pinia/src/types.ts @@ -572,7 +572,11 @@ export type _ActionsTree = Record * For internal use **only** */ export type _ExtractStateFromSetupStore_Keys = keyof { - [K in keyof SS as SS[K] extends _Method | ComputedRef ? never : K]: any + [K in keyof SS as SS[K] extends _Method | ComputedRef + ? SS[K] extends WritableComputedRef + ? K + : never + : K]: any } /** diff --git a/packages/pinia/test-dts/mapHelpers.test-d.ts b/packages/pinia/test-dts/mapHelpers.test-d.ts index 3d2770a05e..924be8aa8d 100644 --- a/packages/pinia/test-dts/mapHelpers.test-d.ts +++ b/packages/pinia/test-dts/mapHelpers.test-d.ts @@ -9,8 +9,7 @@ import { TypeEqual, } from './' -const useOptionsStore = defineStore({ - id: 'name', +const useOptionsStore = defineStore('name', { state: () => ({ a: 'on' as 'on' | 'off', nested: { counter: 0 } }), getters: { upper: (state) => state.a.toUpperCase(), @@ -29,22 +28,28 @@ const useOptionsStore = defineStore({ const useSetupStore = defineStore('setupStore', () => { const a = ref('on' as 'on' | 'off') const upper = computed(() => a.value.toUpperCase()) + const writableUpper = computed({ + get() { + return a.value.toUpperCase() as 'on' | 'off' + }, + set(value: 'on' | 'off') { + a.value = value + }, + }) function toggleA() { a.value = a.value === 'off' ? 'on' : 'off' } function setToggle(aVal: 'on' | 'off') { return (a.value = aVal) } - return { a, upper, toggleA, setToggle } + return { a, upper, writableUpper, toggleA, setToggle } }) -const useCounter = defineStore({ - id: 'counter', +const useCounter = defineStore('counter', { state: () => ({ n: 0 }), }) -const useStoreDos = defineStore({ - id: 'dos', +const useStoreDos = defineStore('dos', { state: () => ({}), }) @@ -167,3 +172,24 @@ expectType< typeof setupStoreWithGetters > >(true) + +const setupStoreWithWritableGetters = mapWritableState(useSetupStore, [ + 'a', + 'writableUpper', +]) + +expectType< + TypeEqual< + { + a: { + get: () => 'on' | 'off' + set: (v: 'on' | 'off') => any + } + writableUpper: { + get: () => 'on' | 'off' + set: (v: 'on' | 'off') => any + } + }, + typeof setupStoreWithWritableGetters + > +>(true)