]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
docs(getters): ts limitation
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 30 Apr 2021 15:36:38 +0000 (17:36 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 30 Apr 2021 15:36:38 +0000 (17:36 +0200)
docs/cookbook/composing-stores.md
docs/core-concepts/getters.md
docs/introduction.md

index 204bc7ad40b49326c9e491288a3586fd7eb55dfa..9aba33cb94627d4bbe3735be6b8bbc08f97b1108 100644 (file)
@@ -15,10 +15,10 @@ export const cartStore = defineStore({
   id: 'cart',
   getters: {
     // ... other getters
-    summary() {
+    summary(state) {
       const user = useUserStore()
 
-      return `Hi ${user.name}, you have ${this.list.length} items in your cart. It costs ${this.price}.`
+      return `Hi ${user.name}, you have ${state.list.length} items in your cart. It costs ${state.price}.`
     },
   },
 
index 8379df96ab4888da3e4b695dd87aa63a2642ff49..235e166f859dc7c3119640819bf6913153e7bb3d 100644 (file)
@@ -1,6 +1,6 @@
 # Getters
 
-Getters are exactly the equivalent of [computed values](https://v3.vuejs.org/guide/reactivity-computed-watchers.html#computed-values) for the state of a Store. They can be defined with the `getters` property in `defineStore()`:
+Getters are exactly the equivalent of [computed values](https://v3.vuejs.org/guide/reactivity-computed-watchers.html#computed-values) for the state of a Store. They can be defined with the `getters` property in `defineStore()`. They receive the `state` as the first parameter **to encourage** the usage of arrow function:
 
 ```js
 export const useStore = defineStore({
@@ -9,14 +9,32 @@ export const useStore = defineStore({
     counter: 0,
   }),
   getters: {
-    doubleCount() {
-      return this.counter * 2
-    },
+    doubleCount: (state) => state.counter * 2,
   },
 })
 ```
 
-Like [actions](./actions.md), getters get access to the _whole store instance_ through `this` with **full typing (and autocompletion ✨) support**.
+Most of the time, getters will only rely on the state, however, they might need to use other getters. Because of this, we can get access to the _whole store instance_ through `this` when defining a regular function **but it is necessary to define the type of the return type (in TypeScript)**. This is due to a known limitation in TypeScript and **doesn't affect getters defined with an arrow function nor getters not using `this`**:
+
+```ts
+export const useStore = defineStore({
+  id: 'main',
+  state: () => ({
+    counter: 0,
+  }),
+  getters: {
+    // automatically infers the return type as a number
+    doubleCount(state) {
+      return state.counter * 2
+    },
+    // the return type **must** be explicitly set
+    doublePlusOne(): number {
+      // autocompletion and typings for the whole store ✨
+      return this.state * 2 + 1
+    },
+  },
+})
+```
 
 Then you can access the getter directly on the store instance:
 
@@ -38,7 +56,7 @@ export default {
 
 ## Accessing other getters
 
-As with computed properties, you can combine multiple getters. Access any other getter via `this`:
+As with computed properties, you can combine multiple getters. Access any other getter via `this`. Even if you are not using TypeScript, you can hint your IDE for types with the [JSDoc](https://jsdoc.app/tags-returns.html):
 
 ```js
 export const useStore = defineStore({
@@ -47,9 +65,15 @@ export const useStore = defineStore({
     counter: 0,
   }),
   getters: {
-    doubleCount() {
-      return this.counter * 2
-    },
+    // type is automatically inferred because we are not using `this`
+    doubleCount: (state) => state.counter * 2,
+    // here we need to add the type ourselves (using JSDoc in JS). We can also
+    // use this to document the getter
+    /**
+     * Returns the counter value times two plus one.
+     *
+     * @returns {number}
+     */
     doubleCountPlusOne() {
       // autocompletion ✨
       return this.doubleCount + 1
@@ -71,9 +95,9 @@ export const useStore = defineStore({
     // ...
   }),
   getters: {
-    otherGetter() {
+    otherGetter(state) {
       const otherStore = useOtherStore()
-      return this.localData + otherStore.data
+      return state.localData + otherStore.data
     },
   },
 })
index 406e87352b28d7831f29d2429ea1b4787713c03a..8cad4e8724ac07e9f8245d42360c25f0cdd5c09b 100644 (file)
@@ -42,13 +42,16 @@ If you are still not into `setup()` and Composition API, don't worry, Pinia also
 const useCounterStore = defineStore({
   id: 'counter',
   state: () => ({ count: 0 }),
-  getters: { double: state => state.count * 2 },
+  getters: {
+    double: (state) => state.count * 2,
+  },
   actions: {
     increment() {
       this.count++
     }
   }
 })
+
 const useUserStore = defineStore({ id: 'user' })
 
 export default {
@@ -91,14 +94,17 @@ export const todos = defineStore({
     nextId: 0,
   }),
   getters: {
-    finishedTodos() {
+    finishedTodos(state) {
       // autocompletion! ✨
-      return this.todos.filter((todo) => todo.isFinished)
+      return state.todos.filter((todo) => todo.isFinished)
     },
-    unfinishedTodos() {
-      return this.todos.filter((todo) => !todo.isFinished)
+    unfinishedTodos(state) {
+      return state.todos.filter((todo) => !todo.isFinished)
     },
-    filteredTodos() {
+    /**
+     * @returns {{ text: string, id: number, isFinished: boolean }[]}
+     */
+    filteredTodos(state) {
       if (this.filter === 'finished') {
         // call other getters with autocompletion ✨
         return this.finishedTodos