Creating base pinia action that can be mixed-in to several stores with typescript

21 Views Asked by At

I am trying to create generic actions that can be mixed-in to several pinia stores. However I don't manage to make the types work. Consider the following base state and actions :

import { Store, defineStore } from 'pinia'

interface Actions<T> {
    a1: (this: _Store<T>) => void
    a2: (this: _Store<T>) => void
}

interface State {}
interface Getters {}

type _Store<T> = Store<
    string,
    State,
    Getters,
    Actions<T>
>

const makeActions = <T>(): Actions<T> => ({
    a1() {
        // $patch is available here
        this.$patch({})
    },
    a2() {
        // a1 is available here
        this.a1()
    }
})

Then, seems simple enough ... however if I try to create a store that extends these actions :

const useMyStore = defineStore('MyStore', {
    state: (): State => ({}),
    actions: {
        ...makeActions<number>(),
        a3(this: _Store<number>) {
            this.$patch({})
            this.a1()
        },
    },
})

Then when using it, I'm getting an error, because the this of the extended store doesn't correspond with the this of the base actions.

const store = useMyStore()
// TS error :
// 'this' context of type 
//     'Store<"MyStore", MyState, {}, { 
//         a3(this: Store<number>): void; 
//         a1: (this: _Store<number>) => void; 
//         a2: (this: _Store<number>) => void; }
//     >' 
// is not assignable to method's 'this' of type '_Store<number>'.
store.a1()

Any idea how to fix these types elegantly ?

0

There are 0 best solutions below