Store with array of compostables - TS interface error #2842
-
Hello, I will illustrate this with a simple example (with just one composable for simplicity). Suppose I have an animal composable export const useAnimal = (_name: string, _weight: number): Animal => {
const id = ref<string>(nanoid());
const name = ref<string>(_name);
const weight = ref<number>(_weight);
watch(weight, (newWeight, oldWeight) => {
if (newWeight === 0) {
console.log(`${name.value} is dead ;(`);
} else if (newWeight > oldWeight) {
console.log(`${name.value} has gained weight`);
} else if (newWeight < oldWeight) {
console.log(`${name.value} has lost weight`);
}
});
return {
id,
name,
weight
};
}; Then the Animal interface for this composable is export interface Animal {
id: Ref<string>;
name: Ref<string>;
weight: Ref<number>;
} But when I try to use this interface with a store, like so: export const useAnimalStoreStore = defineStore('animalStore', () => {
const animals = ref<Animal[]>([]);
function get(animalId: string): Animal | undefined {
return animals.value.find(animal => animal.id === animalId);
}
function add(animal: Animal) {
animals.value.push({ ...animal });
}
return {
animals,
get,
add,
};
}); I get a TS warning
But if I change the deffinition of an Animal to export interface Animal {
id: string;
name: string;
weight: number;
} Then I will get complains in the composable
Finally if I don't specify the return type of the composable, export const useAnimal = (_name: string, _weight: number) => { Then I get an error on animalStore.add(useAnimal('Dog', 60)); I think the whole problem comes from the fact that Pinia is unwrapping refs of the composable. If there a solution that satisfies both composable and store type declaration? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
The resolution I'be found is to start with the interface for the composable export interface AnimalComposable {
id: Ref<string>;
name: Ref<string>;
weight: Ref<number>;
} Then, using UnwrapNestedRefs, I generate a type for the store items export type Animal = UnwrapNestedRefs<AnimalComposable>; With this the store definition looks as follows export const useAnimalStore = defineStore('animalStore', () => {
const animals = ref<Animal[]>([]);
function get(animalId: string): Animal | undefined {
return animals.value.find((animal) => animal.id === animalId);
}
function add(animal: Animal | AnimalComposable) {
animals.value.push(isAnimalComposable(animal) ? reactive(animal) : animal);
}
return {
animals,
get,
add,
};
}); Working demo here: |
Beta Was this translation helpful? Give feedback.
The resolution I'be found is to start with the interface for the composable
Then, using UnwrapNestedRefs, I generate a type for the store items
With this the store definition looks as follows