vuejs / pinia

🍍 Intuitive, type safe, light and flexible Store for Vue using the composition api with DevTools support
https://pinia.vuejs.org
MIT License
12.91k stars 1.02k forks source link

Combining setup stores results in a store with type never. #2566

Closed shai1918 closed 7 months ago

shai1918 commented 7 months ago

Reproduction

https://play.pinia.vuejs.org/#eNqVVE1T2zAQ/SsaXxwaR4bScoCESctwoIe2Ezj64tjrILAljT5COhn/966k2Nhpy9BDZmzte2/fPnmzj75ISbcWostorgvFpCEajJWkzvlmkUVGZ9F1xlkjhTJkT6yGlRDm3ggFpCWVEg2JaarwjGp3SI2OM57xQnCNWh63GNEmJxmfp6EZSuOLgUbWuQF8I2S+tsYITpZFzYpntBBkC2G5mU7RzR0vFDTA0c4+NAhF0rbzNJBRaJ72qlESBf+zJpf0SQuO0+5dr+xQwCEviT9xZ5JxlruTLEr9MwXdzNZKvGhQyM+ipIMuMbq0hK0RotazXLJAezRG6ss0LUqO+BJqtlWUg0m5bNI/OMsL+pmepTVbp9goZbyE3bgNMmYlNO9R76DLU3r2iV541e35QbRxqk60zXiLsRiN11SxzVEohWgkq0H9kIbhNY7CyetavHzzZ0ZZ6C0Wj1A8/+X8Se+C658KML4tDMYyudqACeXb+++ww+e+2IjS1oh+o7gCLWrrPAbYV8tLtD3Aebd3/o4Z3zzo250BrruhnFGfhsf7mG/eGP3V7jk9H6Q4+vgxxX5ZFFQJcWFaA2W/LdglvupXyvySgNAVVP8A7EkJFeMwXjn/XY5QuGI3bg1AHS+n3w78cr1Fx8k47DwrLOlopxfDdpPYzRYnZHJCFtchicA5aHaco+aTE9+FYALGKo7uKA1L2rtDQBtQPoGhgZUnPeDx3NVENXJ4fYWRj0b6j9TVO2NFnPsdxzQK+Cipg6VBWCgwigsZ6G1yimMPSjxvnJarxLelzVUp4jGiFHZdh94I7CabhDZemW7z2gL5QD52zMrywn3BhHX/lgg/WHK6PWk6PTDabujBrXlc4i0mQxvJq6y7SSThXUbtbwx1K04=

Steps to reproduce the bug

  1. Create a setup store, for example the counter store:
import { ref, computed } from 'vue';
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0);
  const name = ref('Eduardo');
  const doubleCount = computed(() => count.value * 2);
  function increment() {
    count.value++;
  }

  return { count, name, doubleCount, increment };
});
  1. Use it in another store:
import { ref, computed } from 'vue';
import { defineStore } from 'pinia';
import { useCounterStore } from './counter.store';

export const useRootStore = defineStore('root', () => {
  const counterStore = useCounterStore();

  return { ...counterStore };
});

type RootStore = ReturnType<typeof useRootStore>;
  1. RootStore is of type never.

Expected behavior

RootStore is of type _StoreWithState.

Actual behavior

RootStore is of type never;

Additional information

For some reason, the returned combined store has type never. However, the useRootStore function has the correct type of StoreDefinition, and correctly sees all state and functions.

posva commented 7 months ago

Spreading a store into another one is likely not what you want to do as it will break reactivity. The final type for this doesn't really matter as it's not supported nor encouraged. I suggest you open a discussion if you want to ask for help with a typing question.

shai1918 commented 7 months ago

Spreading a store into another one is likely not what you want to do as it will break reactivity. The final type for this doesn't really matter as it's not supported nor encouraged. I suggest you open a discussion if you want to ask for help with a typing question.

@posva In my project, I'm maintaining the reactivity by also using storeToRefs, like this:

export const useStore: any = defineStore('root', () => {
  const store1= counterStore();
  const store2= userStore();

  return {
    ...store1,
    ...store2,

    ...storeToRefs(store1),
    ...storeToRefs(store2),
  };
});

Is there a recommended official way of doing this kind of thing, combining stores?

Also, thanks for the quick reply!