Search code examples
typescriptpinia

Pinia + TS: type of store as an argument to a function


I have several different pinia stores that share a bunch of functions. For example

const storeOne = defineStore('a', () => {
    const foo = () => alert('store a');
    const bar = () => alert('bar');
    const a = ref(null);
    return {
        foo,
        bar,
        a
    }
});

const storeTwo = defineStore('b', () => {
    const foo = () => alert('store b');
    const foobar = () => alert('foobar');
    const b = ref(null);
    return {
        foo,
        foobar,
        b
    }
})

both stores will have a function foo in this case. The rest can basically be ignored in that scenario, it's just an example.

I have a function that needs to call foo() and I would like to pass a store in that function but I don't know how I could type this properly. My current attempts for example were:

type StoreCollection = ReturnType<typeof storeTwo| typeof storeOne>
type PickedStoreCollection = Pick<StoreCollection, 'foo'>
const callStoreFunction = (store: PickedStoreCollection) => {
    store.foo(); // works great -> this will know the correct store
}

callStoreFunction(storeOne); // TS error: types a incompatible
callStoreFunction(storeTwo); // TS error: types a incompatible

I made a basic example here https://codesandbox.io/p/sandbox/relaxed-scooby-ubncqg?file=%2Fsrc%2Fmain.ts%3A20%2C1 in the main.ts file

I know I could easily cast every call like this to

callStoreFunction(storeTwo as unknown as PickedStoreCollection);

But I would really like to avoid this.


Solution

  • You missed the store creation

    defineStore resurns not a store: Store, but a useStore: () => Store

    callStoreFunction(storeOne())
    // or renamed
    const storeTwo = useStoreTwo();
    callStoreFunction(storeTwo)