name: 'Eduardo',
}),
getters: {
- upperCaseName() {
- return this.name.toUpperCase()
+ upperCaseName(store) {
+ return store.name.toUpperCase()
},
- doubleName() {
+ doubleName(): string {
return this.upperCaseName
},
- composed() {
+ composed(): string {
return this.upperCaseName + ': ok'
},
},
id: 'A',
state: () => ({ a: 'a' }),
getters: {
- fromB() {
+ fromB(): string {
const bStore = useB()
return this.a + ' ' + bStore.b
},
},
}),
getters: {
- double() {
- return this.n * 2
+ double(state) {
+ return state.n * 2
},
- notA() {
- return !this.a
+ notA(state) {
+ return !state.a
},
},
})
},
}),
getters: {
- double() {
- return this.n * 2
+ double(state) {
+ return state.n * 2
},
- notA() {
- return !this.a
+ notA(state) {
+ return !state.a
},
},
actions: {
rawItems: [] as string[],
}),
getters: {
- items() {
- return this.rawItems.reduce((items, item) => {
+ items: (state) =>
+ state.rawItems.reduce((items, item) => {
const existingItem = items.find((it) => it.name === item)
if (!existingItem) {
}
return items
- }, [] as { name: string; amount: number }[])
- },
+ }, [] as { name: string; amount: number }[]),
},
+
actions: {
addItem(name: string) {
this.rawItems.push(name)
},
},
getters: {
- test() {
- return this.name.toUpperCase()
+ test(state) {
+ return state.name.toUpperCase()
},
},
})
},
getters: {
- doubleN() {
- return this.n * 2
- },
+ doubleN: (state) => state.n * 2,
},
})
import { ComponentInstance } from '@vue/devtools-api'
import {
GenericStore,
+ GettersTree,
Method,
StateTree,
Store,
function getCachedStore<
Id extends string = string,
S extends StateTree = StateTree,
- G = Record<string, Method>,
+ G extends GettersTree<S> = GettersTree<S>,
A = Record<string, Method>
>(
vm: ComponentInstance,
}, {} as Spread<Stores>)
}
-type MapStateReturn<S extends StateTree, G> = {
+type MapStateReturn<S extends StateTree, G extends GettersTree<S>> = {
[key in keyof S | keyof G]: () => Store<string, S, G, {}>[key]
}
type MapStateObjectReturn<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
A,
T extends Record<
string,
export function mapState<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
A,
KeyMapper extends Record<
string,
* @param useStore - store to map from
* @param keys - array of state properties or getters
*/
-export function mapState<Id extends string, S extends StateTree, G, A>(
+export function mapState<
+ Id extends string,
+ S extends StateTree,
+ G extends GettersTree<S>,
+ A
+>(
useStore: StoreDefinition<Id, S, G, A>,
keys: Array<keyof S | keyof G>
): MapStateReturn<S, G>
export function mapState<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
A,
KeyMapper extends Record<
string,
export function mapActions<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
A,
KeyMapper extends Record<string, keyof A>
>(
* @param useStore - store to map from
* @param keys - array of action names to map
*/
-export function mapActions<Id extends string, S extends StateTree, G, A>(
+export function mapActions<
+ Id extends string,
+ S extends StateTree,
+ G extends GettersTree<S>,
+ A
+>(
useStore: StoreDefinition<Id, S, G, A>,
keys: Array<keyof A>
): MapActionsReturn<A>
export function mapActions<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
A,
KeyMapper extends Record<string, keyof A>
>(
export function mapWritableState<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
A,
KeyMapper extends Record<string, keyof S>
>(
* @param useStore - store to map from
* @param keys - array of state properties
*/
-export function mapWritableState<Id extends string, S extends StateTree, G, A>(
+export function mapWritableState<
+ Id extends string,
+ S extends StateTree,
+ G extends GettersTree<S>,
+ A
+>(
useStore: StoreDefinition<Id, S, G, A>,
keys: Array<keyof S>
): MapWritableStateReturn<S>
export function mapWritableState<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
A,
KeyMapper extends Record<string, keyof S>
>(
Method,
DefineStoreOptions,
Store,
+ GettersTree,
} from './types'
/**
export interface PiniaPluginContext<
Id extends string = string,
S extends StateTree = StateTree,
- G = Record<string, Method>,
+ G extends GettersTree<S> = GettersTree<S>,
A = Record<string, Method>
> {
/**
DefineStoreOptions,
StoreDefinition,
GenericStore,
+ GettersTree,
} from './types'
import {
getActivePinia,
function buildStoreToUse<
Id extends string,
S extends StateTree,
- G extends Record<string, Method>,
+ G extends GettersTree<S>,
A extends Record<string, Method>
>(
partialStore: StoreWithState<Id, S>,
computedGetters[getterName] = computed(() => {
setActivePinia(pinia)
// eslint-disable-next-line @typescript-eslint/no-use-before-define
+ // @ts-expect-error: the argument count is correct
return getters[getterName].call(store, store)
}) as StoreWithGetters<G>[typeof getterName]
}
Id extends string,
S extends StateTree,
// the omission of the extends is necessary for type inference
- G /* extends Record<string, Method> */,
+ G extends GettersTree<S>,
A /* extends Record<string, Method> */
>(options: DefineStoreOptions<Id, S, G, A>): StoreDefinition<Id, S, G, A> {
const { id, state, getters, actions } = options
storeAndDescriptor[0],
storeAndDescriptor[1],
id,
- getters as Record<string, Method> | undefined,
+ getters as GettersTree<S> | undefined,
actions as Record<string, Method> | undefined,
// @ts-ignore: because we don't have extend on G and A
options
storeAndDescriptor[0],
storeAndDescriptor[1],
id,
- getters as Record<string, Method> | undefined,
+ getters as GettersTree<S> | undefined,
actions as Record<string, Method> | undefined,
// @ts-ignore: because we don't have extend on G and A
options
export type Store<
Id extends string,
S extends StateTree,
- G,
+ G extends GettersTree<S>,
// has the actions without the context (this) for typings
A
> = StoreWithState<Id, S> &
StoreWithActions<A> &
PiniaCustomProperties<Id, S, G, A>
+// TODO: check if it's possible to add = to StoreDefinition and Store and cleanup GenericStore and the other one
+
/**
* Return type of `defineStore()`. Function that allows instantiating a store.
*/
export interface StoreDefinition<
Id extends string,
S extends StateTree,
- G /* extends Record<string, StoreGetterThis> */,
+ G extends GettersTree<S>,
A /* extends Record<string, StoreAction> */
> {
(pinia?: Pinia | null | undefined): Store<Id, S, G, A>
export type GenericStore = Store<
string,
StateTree,
- Record<string, Method>,
+ GettersTree<StateTree>,
Record<string, Method>
>
export type GenericStoreDefinition = StoreDefinition<
string,
StateTree,
- Record<string, Method>,
+ GettersTree<StateTree>,
Record<string, Method>
>
export interface PiniaCustomProperties<
Id extends string = string,
S extends StateTree = StateTree,
- G = Record<string, Method>,
+ G extends GettersTree<S> = GettersTree<S>,
A = Record<string, Method>
> {}
+export type GettersTree<S extends StateTree> = Record<
+ string,
+ ((state: S) => any) | (() => any)
+>
+
/**
* Options parameter of `defineStore()`. Can be extended to augment stores with
* the plugin API.
export interface DefineStoreOptions<
Id extends string,
S extends StateTree,
- G /* extends Record<string, StoreGetterThis> */,
+ G extends GettersTree<S>,
A /* extends Record<string, StoreAction> */
> {
id: Id
id: 'name',
state: () => ({ a: 'on' as 'on' | 'off', nested: { counter: 0 } }),
getters: {
- upper() {
+ upper(): string {
return this.a.toUpperCase()
},
},
id: 'name',
state: () => ({ a: 'on' as 'on' | 'off', nested: { counter: 0 } }),
getters: {
- upper() {
+ upper(): string {
return this.a.toUpperCase()
},
},
id: 'name',
state: () => ({ a: 'on' as 'on' | 'off', nested: { counter: 0 } }),
getters: {
- upper() {
+ upper: (state) => {
+ expectType<'on' | 'off'>(state.a)
+ return state.a.toUpperCase() as 'ON' | 'OFF'
+ },
+ upperThis(): 'ON' | 'OFF' {
expectType<'on' | 'off'>(this.a)
- return this.a.toUpperCase()
+ return this.a.toUpperCase() as 'ON' | 'OFF'
},
- other() {
+ other(): false {
expectType<string>(this.upper)
return false
},