From 8e82c69aa811fcbb7ebb9fa6349440bc8a4439f9 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 28 Jul 2021 15:15:28 +0200 Subject: [PATCH] types: mark and document more types --- docs/core-concepts/plugins.md | 26 ++++++++++++++++++-------- src/index.ts | 4 +++- src/store.ts | 15 +++++++++++++++ src/testing.ts | 8 ++++++-- src/types.ts | 13 +++++++++---- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/docs/core-concepts/plugins.md b/docs/core-concepts/plugins.md index 00e56563..64c8178f 100644 --- a/docs/core-concepts/plugins.md +++ b/docs/core-concepts/plugins.md @@ -287,7 +287,7 @@ pinia.use(({ store }) => { }) ``` -`PiniaCustomProperties` is a generic type that allows you to reference properties of a store. Imagine the following example where we copy over the initial options as `$options`: +`PiniaCustomProperties` is a generic type that allows you to reference properties of a store. Imagine the following example where we copy over the initial options as `$options` (this would only work for option stores): ```ts pinia.use(({ options }) => ({ $options: options })) @@ -299,17 +299,27 @@ We can properly type this by using the 4 generic types of `PiniaCustomProperties import 'pinia' declare module 'pinia' { - export interface PiniaCustomProperties { + export interface PiniaCustomProperties { $options: { id: Id - state?: () => State - getters?: Getters - actions?: Actions + state?: () => S + getters?: G + actions?: A } } } ``` +:::tip +When extending types in generics, they must be named **exactly as in the source code**. `Id` cannot be named `id` or `I`, and `S` cannot be named `State`. Here is what every letter stands for: + +- S: State +- G: Getters +- A: Actions +- SS: Setup Store / Store + +::: + ### Typing new state When adding new state properties (to both, the `store` and `store.$state`), you need to add the type to `PiniaCustomStateProperties` instead. Differently from `PiniaCustomProperties`, it only receives the `State` generic: @@ -318,7 +328,7 @@ When adding new state properties (to both, the `store` and `store.$state`), you import 'pinia' declare module 'pinia' { - export interface PiniaCustomStateProperties { + export interface PiniaCustomStateProperties { hello: string } } @@ -326,13 +336,13 @@ declare module 'pinia' { ### Typing new creation options -When creating new options for `defineStore()`, you should extend the `DefineStoreOptions`. Like `PiniaCustomProperties`, it also exposes all the generics that define a store, allowing you to limit what can be defined. For example, you can une the names of the actions: +When creating new options for `defineStore()`, you should extend the `DefineStoreOptionsBase`. Differently from `PiniaCustomProperties`, it only exposes two generics: the State and the Store type, allowing you to limit what can be defined. For example, you can une the names of the actions: ```ts import 'pinia' declare module 'pinia' { - export interface DefineStoreOptions { + export interface DefineStoreOptionsBase { debounce?: { // allow defining a number of ms for any of the actions [k in keyof A]?: number diff --git a/src/index.ts b/src/index.ts index 99fba833..17edf463 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ export type { StateTree, Store, StoreGeneric, + // TODO: remove in release GenericStore, StoreDefinition, StoreWithGetters, @@ -17,6 +18,7 @@ export type { _Method, StoreWithActions, StoreWithState, + StoreProperties, StoreOnActionListener, StoreOnActionListenerContext, SubscriptionCallback, @@ -56,6 +58,6 @@ export type { } from './mapHelpers' export { createTestingPinia } from './testing' -export type { TestingOptions } from './testing' +export type { TestingOptions, TestingPinia } from './testing' export { acceptHMRUpdate } from './hmr' diff --git a/src/store.ts b/src/store.ts index d64c10ec..5eaf7edd 100644 --- a/src/store.ts +++ b/src/store.ts @@ -574,6 +574,9 @@ function createSetupStore< // } +/** + * @internal + */ type _SpreadStateFromStore = K extends readonly [ infer A, ...infer Rest @@ -587,6 +590,9 @@ type _SpreadStateFromStore = K extends readonly [ : {} : {} +/** + * @internal + */ type _SpreadPropertiesFromObject< SS, K extends readonly any[], @@ -599,17 +605,26 @@ type _SpreadPropertiesFromObject< : {} : {} +/** + * @internal + */ type _ExtractStateFromSetupStore = _SpreadStateFromStore< SS, _UnionToTuple > +/** + * @internal + */ type _ExtractActionsFromSetupStore = _SpreadPropertiesFromObject< SS, _UnionToTuple, _Method > +/** + * @internal + */ type _ExtractGettersFromSetupStore = _SpreadPropertiesFromObject< SS, _UnionToTuple, diff --git a/src/testing.ts b/src/testing.ts index d08b844f..f93ab03c 100644 --- a/src/testing.ts +++ b/src/testing.ts @@ -40,6 +40,10 @@ export interface TestingOptions { createSpy?: (fn?: (...args: any[]) => any) => (...args: any[]) => any } +/** + * Pinia instance specifically designed for testing. Extends a regular + * {@link Pinia} instance with test specific properties. + */ export interface TestingPinia extends Pinia { /** * Clears the cache of spies used for actions. @@ -58,7 +62,7 @@ export interface TestingPinia extends Pinia { * they are replaced with `jest.fn()`, otherwise, you must provide your own * `createSpy` option. * - * @internal - STILL NOT RELEASED, DO NOT USE. It will be likely moved to its + * @alpha - STILL NOT RELEASED, DO NOT USE. It will be likely moved to its * own package. * * @param options - options to configure the testing pinia @@ -75,7 +79,7 @@ export function createTestingPinia({ plugins.forEach((plugin) => pinia.use(plugin)) - // @ts-ignore + // @ts-ignore: this can fail in TS depending of the existence of jest createSpy = createSpy || (typeof jest !== undefined && jest.fn) if (!createSpy) { throw new Error('You must configure the `createSpy` option.') diff --git a/src/types.ts b/src/types.ts index 7a38a2e5..b1a12727 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,6 +18,11 @@ export function isPlainObject( ) } +/** + * Recursive `Partial`. Used by {@link Store.$patch}. + * + * @internal + */ export type DeepPartial = { [K in keyof T]?: DeepPartial } // type DeepReadonly = { readonly [P in keyof T]: DeepReadonly } @@ -493,7 +498,7 @@ export interface StoreDefinition< } /** - * Properties that are added to every store by `pinia.use()` + * Properties that are added to every store by `pinia.use()`. */ export interface PiniaCustomProperties< Id extends string = string, @@ -503,12 +508,12 @@ export interface PiniaCustomProperties< > {} /** - * Properties that are added to every `store.$state` by `pinia.use()` + * Properties that are added to every `store.$state` by `pinia.use()`. */ export interface PiniaCustomStateProperties {} /** - * Type of an object of Getters that infers the argument + * Type of an object of Getters that infers the argument. * * @internal */ @@ -519,7 +524,7 @@ export type GettersTree = Record< > /** - * Type of an object of Actions + * Type of an object of Actions. * * @internal */ -- 2.47.2