mapGetters,
mapState,
mapStores,
+ mapWritableState,
setMapStoreSuffix,
} from '../src'
import { mount } from '@vue/test-utils'
expect(wrapper.vm.set(4)).toBe(4)
})
})
+
+ describe('mapWritableState', () => {
+ async function testComponent(
+ computedProperties: any,
+ template: string,
+ expectedText: string,
+ expectedText2: string
+ ) {
+ const pinia = createPinia()
+ const Component = defineComponent({
+ template: `<p>${template}</p>`,
+ computed: {
+ ...computedProperties,
+ },
+ methods: Object.keys(computedProperties).reduce((methods, name) => {
+ // @ts-ignore
+ methods['set_' + name] = function (v: any) {
+ // @ts-ignore
+ this[name] = v
+ }
+ return methods
+ }, {}),
+ })
+
+ const wrapper = mount(Component, { global: { plugins: [pinia] } })
+
+ expect(wrapper.text()).toBe(expectedText)
+
+ for (const key in computedProperties) {
+ // @ts-ignore
+ wrapper.vm['set_' + key]('replaced')
+ }
+
+ await nextTick()
+
+ expect(wrapper.text()).toBe(expectedText2)
+ }
+
+ it('array', async () => {
+ await testComponent(
+ mapWritableState(useStore, ['n', 'a']),
+ `{{ n }} {{ a }}`,
+ `0 true`,
+ 'replaced replaced'
+ )
+ })
+
+ it('object', async () => {
+ await testComponent(
+ mapWritableState(useStore, { count: 'n', myA: 'a' }),
+ `{{ count }} {{ myA }}`,
+ `0 true`,
+ 'replaced replaced'
+ )
+ })
+ })
})
}, {} as MapActionsObjectReturn<A, KeyMapper>)
}
+type MapWritableStateReturn<S extends StateTree> = {
+ [key in keyof S]: {
+ get: () => Store<string, S, {}, {}>[key]
+ set: (value: Store<string, S, {}, {}>[key]) => any
+ }
+}
+
+type MapWritableStateObjectReturn<
+ S extends StateTree,
+ T extends Record<string, keyof S>
+> = {
+ [key in keyof T]: {
+ get: () => Store<string, S, {}, {}>[T[key]]
+ set: (value: Store<string, S, {}, {}>[T[key]]) => any
+ }
+}
+
/**
* Same as `mapState()` but creates computed setters as well so the state can be
* modified. Differently from `mapState()`, only `state` properties can be
>(
useStore: StoreDefinition<Id, S, G, A>,
keyMapper: KeyMapper
-): MapStateObjectReturn<Id, S, G, A, KeyMapper>
+): MapWritableStateObjectReturn<S, KeyMapper>
/**
* Allows using state and getters from one store without using the composition
* API (`setup()`) by generating an object to be spread in the `computed` field
export function mapWritableState<Id extends string, S extends StateTree, G, A>(
useStore: StoreDefinition<Id, S, G, A>,
keys: Array<keyof S>
-): MapStateReturn<S, G>
+): MapWritableStateReturn<S>
/**
* Allows using state and getters from one store without using the composition
* API (`setup()`) by generating an object to be spread in the `computed` field
>(
useStore: StoreDefinition<Id, S, G, A>,
keysOrMapper: Array<keyof S> | KeyMapper
-): MapStateReturn<S, G> | MapStateObjectReturn<Id, S, G, A, KeyMapper> {
+): MapWritableStateReturn<S> | MapWritableStateObjectReturn<S, KeyMapper> {
return Array.isArray(keysOrMapper)
? keysOrMapper.reduce((reduced, key) => {
reduced[key] = {
get(this: ComponentInstance) {
return getCachedStore(this, useStore)[key]
},
- set() {},
+ set(value) {
+ // it's easier to type it here as any
+ return (getCachedStore(this, useStore)[key] = value as any)
+ },
}
return reduced
- }, {} as MapStateReturn<S, G>)
+ }, {} as MapWritableStateReturn<S>)
: Object.keys(keysOrMapper).reduce((reduced, key: keyof KeyMapper) => {
+ // @ts-ignore
reduced[key] = {
get(this: ComponentInstance) {
return getCachedStore(this, useStore)[keysOrMapper[key]]
},
- set() {},
+ set(value) {
+ // it's easier to type it here as any
+ return (getCachedStore(this, useStore)[
+ keysOrMapper[key]
+ ] = value as any)
+ },
}
return reduced
- }, {} as MapStateObjectReturn<Id, S, G, A, KeyMapper>)
+ }, {} as MapWritableStateObjectReturn<S, KeyMapper>)
}
-import { defineStore, expectType, mapStores, mapActions, mapState } from '.'
+import {
+ defineStore,
+ expectType,
+ mapStores,
+ mapActions,
+ mapState,
+ mapWritableState,
+} from '.'
const useStore = defineStore({
id: 'name',
newSetToggle: (a: 'on' | 'off') => 'on' | 'off'
newToggleA: () => void
}>(mapActions(useStore, { newSetToggle: 'setToggle', newToggleA: 'toggleA' }))
+
+expectType<{
+ a: {
+ get: () => 'on' | 'off'
+ set: (v: 'on' | 'off') => any
+ }
+}>(mapWritableState(useStore, ['a']))
+
+expectType<{
+ newA: {
+ get: () => 'on' | 'off'
+ set: (v: 'on' | 'off') => any
+ }
+}>(mapWritableState(useStore, { newA: 'a' }))
+
+// @ts-expect-error: cannot use a getter
+mapWritableState(useStore, ['upper'])
+// @ts-expect-error: cannot use a getter
+mapWritableState(useStore, { up: 'upper' })