diff --git a/packages/pinia/src/mapHelpers.ts b/packages/pinia/src/mapHelpers.ts index 4cb219008c..aa7662cb09 100644 --- a/packages/pinia/src/mapHelpers.ts +++ b/packages/pinia/src/mapHelpers.ts @@ -1,7 +1,7 @@ import type { ComponentPublicInstance, ComputedRef, UnwrapRef } from 'vue-demi' import type { _GettersTree, - _Method, + _StoreWithGetters_Writable, StateTree, Store, StoreDefinition, @@ -431,10 +431,21 @@ export function mapActions< /** * For internal use **only** */ -export type _MapWritableStateReturn = { - [key in keyof S]: { - get: () => S[key] - set: (value: S[key]) => any +export type _MapWritableStateKeys = + | keyof UnwrapRef + | keyof _StoreWithGetters_Writable + +/** + * For internal use **only** + */ +export type _MapWritableStateReturn< + S extends StateTree, + G, + Keys extends _MapWritableStateKeys, +> = { + [key in Keys]: { + get: () => UnwrapRef<(S & G)[key]> + set: (value: UnwrapRef<(S & G)[key]>) => any } } @@ -442,12 +453,13 @@ export type _MapWritableStateReturn = { * For internal use **only** */ export type _MapWritableStateObjectReturn< - S, - T extends Record, + S extends StateTree, + G, + KeyMapper extends Record>, > = { - [key in keyof T]: { - get: () => S[T[key]] - set: (value: S[T[key]]) => any + [key in keyof KeyMapper]: { + get: () => UnwrapRef<(S & G)[KeyMapper[key]]> + set: (value: UnwrapRef<(S & G)[KeyMapper[key]]>) => any } } @@ -462,13 +474,13 @@ export type _MapWritableStateObjectReturn< export function mapWritableState< Id extends string, S extends StateTree, - G extends _GettersTree, + G, A, - KeyMapper extends Record>, + KeyMapper extends Record>, >( useStore: StoreDefinition, keyMapper: KeyMapper -): _MapWritableStateObjectReturn, KeyMapper> +): _MapWritableStateObjectReturn /** * 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 @@ -480,13 +492,13 @@ export function mapWritableState< export function mapWritableState< Id extends string, S extends StateTree, - G extends _GettersTree, + G, A, - Keys extends keyof UnwrapRef, + Keys extends _MapWritableStateKeys, >( useStore: StoreDefinition, keys: readonly Keys[] -): Pick<_MapWritableStateReturn>, Keys> +): Pick<_MapWritableStateReturn, Keys> /** * 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 @@ -498,43 +510,51 @@ export function mapWritableState< export function mapWritableState< Id extends string, S extends StateTree, - G extends _GettersTree, + G, A, - KeyMapper extends Record, + Keys extends _MapWritableStateKeys, + KeyArr extends Keys[], + KeyMapper extends Record, >( useStore: StoreDefinition, - keysOrMapper: Array | KeyMapper -): _MapWritableStateReturn | _MapWritableStateObjectReturn { + keysOrMapper: KeyArr | KeyMapper +): + | _MapWritableStateReturn + | _MapWritableStateObjectReturn { return Array.isArray(keysOrMapper) - ? keysOrMapper.reduce((reduced, key) => { - // @ts-ignore - reduced[key] = { - get(this: ComponentPublicInstance) { - // @ts-expect-error: FIXME: should work? - return useStore(this.$pinia)[key] - }, - set(this: ComponentPublicInstance, value) { - // @ts-expect-error: FIXME: should work? - return (useStore(this.$pinia)[key] = value) - }, - } - return reduced - }, {} as _MapWritableStateReturn) + ? keysOrMapper.reduce( + (reduced, key) => { + reduced[key] = { + get(this: ComponentPublicInstance) { + return useStore(this.$pinia)[key] as (S & G)[typeof key] + }, + set( + this: ComponentPublicInstance, + value: Store[typeof key] + ) { + return (useStore(this.$pinia)[key] = value) + }, + } + return reduced + }, + {} as _MapWritableStateReturn + ) : Object.keys(keysOrMapper).reduce( (reduced, key: keyof KeyMapper) => { - // @ts-ignore reduced[key] = { get(this: ComponentPublicInstance) { - // @ts-expect-error: FIXME: should work? - return useStore(this.$pinia)[keysOrMapper[key]] + return useStore(this.$pinia)[keysOrMapper[key]] as (S & + G)[KeyMapper[typeof key]] }, - set(this: ComponentPublicInstance, value) { - // @ts-expect-error: FIXME: should work? + set( + this: ComponentPublicInstance, + value: Store[KeyMapper[typeof key]] + ) { return (useStore(this.$pinia)[keysOrMapper[key]] = value) }, } return reduced }, - {} as _MapWritableStateObjectReturn + {} as _MapWritableStateObjectReturn ) } diff --git a/packages/pinia/src/types.ts b/packages/pinia/src/types.ts index 017eca6af4..4ca20da9e3 100644 --- a/packages/pinia/src/types.ts +++ b/packages/pinia/src/types.ts @@ -572,11 +572,7 @@ export type _ActionsTree = Record * For internal use **only** */ export type _ExtractStateFromSetupStore_Keys = keyof { - [K in keyof SS as SS[K] extends _Method | ComputedRef - ? SS[K] extends WritableComputedRef - ? K - : never - : K]: any + [K in keyof SS as SS[K] extends _Method | ComputedRef ? never : K]: any } /**