From: Eduardo San Martin Morote Date: Fri, 30 Apr 2021 15:36:38 +0000 (+0200) Subject: docs(getters): ts limitation X-Git-Tag: v2.0.0-alpha.14~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1210cfccaef18c6c43c4b1b9945302d72d93d8d;p=thirdparty%2Fvuejs%2Fpinia.git docs(getters): ts limitation --- diff --git a/docs/cookbook/composing-stores.md b/docs/cookbook/composing-stores.md index 204bc7ad..9aba33cb 100644 --- a/docs/cookbook/composing-stores.md +++ b/docs/cookbook/composing-stores.md @@ -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}.` }, }, diff --git a/docs/core-concepts/getters.md b/docs/core-concepts/getters.md index 8379df96..235e166f 100644 --- a/docs/core-concepts/getters.md +++ b/docs/core-concepts/getters.md @@ -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 }, }, }) diff --git a/docs/introduction.md b/docs/introduction.md index 406e8735..8cad4e87 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -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