I'm using mobx-state-tree with Typescript in a React application. And, I'm having an issue with Typescript where it complains about the type of the mobx type types.safeReference
. It looks like the type of safeReference
in the model definition is different from its type when you use .create()
to actually create an instance of the model. In my code, selectedProduct
's type is converted to string | number | undefined | null
in productStore
, but in the model definition is IStateTreeNode<...> | undefined | null
and that's why I get an error in my root store. How can I fix that?
Here's my Product store:
import { types } from "mobx-state-tree";
const Product = types.model("Product", {
id: types.identifier,
name: types.string
})
const ProductStore = types
.model("ProductStore", {
products: types.array(Product),
selectedProduct: types.safeReference(Product),
})
.actions((self) => ({
// actions here
}));
export const productStore = ProductStore.create({
products: [],
selectedProduct: undefined // the type here is different from the type in the actual model
});
And, here's my root store:
import { types } from "mobx-state-tree";
import ProductStore, { productStore } from "./product-store";
const RootStore = types.model('RootStore', {
productStore: ProductStore
})
export const rootStore = RootStore.create({
productStore: productStore // Here is where I get the typescript error.
});
UPDATE:
Another way of reproducing this issue is by trying to create a custom reference. The getter will complain about undefined
not being assignable to type {...}.
const ProductByIdReference = types.maybeNull(
types.reference(Product, {
get(id: number, parent: Instance<typeof ProductStore>) {
return parent.products.find(p => p.id === id) || undefined
},
set(value: Instance<typeof Product>) {
return value.id
}
})
)
ProductStore
singleton, could you not let theRootStore
create it for you? I.e.export const rootStore = RootStore.create({ productStore: { products: [], selectedProduct: undefined } });
– WeekdayRootStore.create
is looking for a raw value rather than a created store. If you pass it the initial state ofproductStore
rather than the store itself then it works fine. Not sure if this is at all useful but this answer shows a very different way to combine stores: https://mcmap.net/q/1470770/-how-to-split-mobx-state-tree-models-across-multiple-files – CitricIMSTArray
github.com/mobxjs/mobx-state-tree/blob/… and it expects an actual array. It complains thatIMSTArray
does not have all of the methods that an array should. – Citric