]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
fix(types): mapHelpers with getters types (#2571) (#2576)
authorRed Huang <redhuang@synology.com>
Thu, 15 Feb 2024 13:49:19 +0000 (21:49 +0800)
committerGitHub <noreply@github.com>
Thu, 15 Feb 2024 13:49:19 +0000 (14:49 +0100)
packages/pinia/src/mapHelpers.ts
packages/pinia/test-dts/index.d.ts
packages/pinia/test-dts/mapHelpers.test-d.ts

index c33d8fbffbb5623ad8c63addf20716903ff48d07..e20b966a79921286dd5ca6789ad40e6a24e85280 100644 (file)
@@ -1,4 +1,4 @@
-import type { ComponentPublicInstance } from 'vue-demi'
+import type { ComponentPublicInstance, ComputedRef } from 'vue-demi'
 import type {
   _GettersTree,
   _Method,
@@ -128,7 +128,7 @@ export function mapStores<Stores extends any[]>(
  */
 export type _MapStateReturn<
   S extends StateTree,
-  G extends _GettersTree<S>,
+  G extends _GettersTree<S> | { [key: string]: ComputedRef },
   Keys extends keyof S | keyof G = keyof S | keyof G,
 > = {
   // [key in keyof S | keyof G]: () => key extends keyof S
@@ -145,7 +145,7 @@ export type _MapStateReturn<
 export type _MapStateObjectReturn<
   Id extends string,
   S extends StateTree,
-  G extends _GettersTree<S>,
+  G extends _GettersTree<S> | { [key: string]: ComputedRef },
   A,
   T extends Record<
     string,
@@ -198,7 +198,7 @@ export type _MapStateObjectReturn<
 export function mapState<
   Id extends string,
   S extends StateTree,
-  G extends _GettersTree<S>,
+  G extends _GettersTree<S> | { [key: string]: ComputedRef },
   A,
   KeyMapper extends Record<
     string,
@@ -235,7 +235,7 @@ export function mapState<
 export function mapState<
   Id extends string,
   S extends StateTree,
-  G extends _GettersTree<S>,
+  G extends _GettersTree<S> | { [key: string]: ComputedRef },
   A,
   Keys extends keyof S | keyof G,
 >(
@@ -254,7 +254,7 @@ export function mapState<
 export function mapState<
   Id extends string,
   S extends StateTree,
-  G extends _GettersTree<S>,
+  G extends _GettersTree<S> | { [key: string]: ComputedRef },
   A,
 >(
   useStore: StoreDefinition<Id, S, G, A>,
index 2e9df04353a7fb433ce705387f173d6344640b37..abd9f63ca5c33b28521daae630bf5d49af896474 100644 (file)
@@ -1,6 +1,10 @@
 export * from '../dist/pinia'
 // export * from '../src'
 
+export type TypeEqual<Target, Value> =
+  (<T>() => T extends Target ? 1 : 2) extends <T>() => T extends Value ? 1 : 2
+    ? true
+    : false
 export function describe(_name: string, _fn: () => void): void
 export function expectType<T>(value: T): void
 export function expectError<T>(value: T): void
index 58ca94366a26997ba59baada69eb4c104ed05744..c6cdd7a84c1b9dcc59a3cd0770a85009e6926864 100644 (file)
@@ -1,3 +1,4 @@
+import { computed, ref } from 'vue'
 import {
   defineStore,
   expectType,
@@ -5,9 +6,10 @@ import {
   mapActions,
   mapState,
   mapWritableState,
+  TypeEqual,
 } from './'
 
-const useStore = defineStore({
+const useOptionsStore = defineStore({
   id: 'name',
   state: () => ({ a: 'on' as 'on' | 'off', nested: { counter: 0 } }),
   getters: {
@@ -24,6 +26,18 @@ const useStore = defineStore({
   },
 })
 
+const useSetupStore = defineStore('setupStore', () => {
+  const a = ref('on' as 'on' | 'off')
+  const upper = computed(() => a.value.toUpperCase())
+  function toggleA() {
+    a.value = a.value === 'off' ? 'on' : 'off'
+  }
+  function setToggle(aVal: 'on' | 'off') {
+    return (a.value = aVal)
+  }
+  return { a, upper, toggleA, setToggle }
+})
+
 const useCounter = defineStore({
   id: 'counter',
   state: () => ({ n: 0 }),
@@ -34,11 +48,11 @@ const useStoreDos = defineStore({
   state: () => ({}),
 })
 
-type MainStore = ReturnType<typeof useStore>
+type MainStore = ReturnType<typeof useOptionsStore>
 type DosStore = ReturnType<typeof useStoreDos>
 type CounterStore = ReturnType<typeof useCounter>
 
-const computedStores = mapStores(useStore, useStoreDos, useCounter)
+const computedStores = mapStores(useOptionsStore, useStoreDos, useCounter)
 
 expectType<{
   nameStore: () => MainStore
@@ -54,24 +68,24 @@ expectType<{
 expectType<{
   a: () => 'on' | 'off'
   upper: () => string
-}>(mapState(useStore, ['a', 'upper']))
+}>(mapState(useOptionsStore, ['a', 'upper']))
 
 // @ts-expect-error
-mapState(useStore, ['a']).nested
+mapState(useOptionsStore, ['a']).nested
 
 // @ts-expect-error
-mapState(useStore, ['a', 'upper']).nested
+mapState(useOptionsStore, ['a', 'upper']).nested
 
 expectType<{
   newA: () => 'on' | 'off'
   newUpper: () => string
-}>(mapState(useStore, { newA: 'a', newUpper: 'upper' }))
+}>(mapState(useOptionsStore, { newA: 'a', newUpper: 'upper' }))
 
 expectType<{
   newA: () => 'on' | 'off'
   newUpper: () => string
 }>(
-  mapState(useStore, {
+  mapState(useOptionsStore, {
     newA: (store) => {
       expectType<string>(store.upper)
       return store.a
@@ -83,19 +97,24 @@ expectType<{
 expectType<{
   setToggle: (a: 'on' | 'off') => 'on' | 'off'
   toggleA: () => void
-}>(mapActions(useStore, ['setToggle', 'toggleA']))
+}>(mapActions(useOptionsStore, ['setToggle', 'toggleA']))
 
 expectType<{
   newSetToggle: (a: 'on' | 'off') => 'on' | 'off'
   newToggleA: () => void
-}>(mapActions(useStore, { newSetToggle: 'setToggle', newToggleA: 'toggleA' }))
+}>(
+  mapActions(useOptionsStore, {
+    newSetToggle: 'setToggle',
+    newToggleA: 'toggleA',
+  })
+)
 
 expectType<{
   a: {
     get: () => 'on' | 'off'
     set: (v: 'on' | 'off') => any
   }
-}>(mapWritableState(useStore, ['a']))
+}>(mapWritableState(useOptionsStore, ['a']))
 // @ts-expect-error: only defined in array
 mapWritableState(useStore, ['a']).b
 
@@ -104,9 +123,33 @@ expectType<{
     get: () => 'on' | 'off'
     set: (v: 'on' | 'off') => any
   }
-}>(mapWritableState(useStore, { newA: 'a' }))
+}>(mapWritableState(useOptionsStore, { newA: 'a' }))
 
 // @ts-expect-error: cannot use a getter
 mapWritableState(useStore, ['upper'])
 // @ts-expect-error: cannot use a getter
 mapWritableState(useStore, { up: 'upper' })
+
+const setupStoreWithState = mapState(useSetupStore, ['a'])
+
+// store with no getters
+expectType<
+  TypeEqual<
+    {
+      a: () => 'on' | 'off'
+    },
+    typeof setupStoreWithState
+  >
+>(true)
+
+const setupStoreWithGetters = mapState(useSetupStore, ['a', 'upper'])
+
+expectType<
+  TypeEqual<
+    {
+      a: () => 'on' | 'off'
+      upper: () => string
+    },
+    typeof setupStoreWithGetters
+  >
+>(true)