Closed benjaminkwokhuen closed 1 year ago
Yeah, this isn't great. I haven't run into this yet because we only use getQueryClient in external stores. Maybe we can solve it on the type level somehow.
I had a similiar problem today, and it's possible to type the root store with a view. (Typing the actual query client seems more difficult.)
// RootStore.ts
export const RootStore = createRootStore({
itemStore: types.optional(createModelStore({ items: types.map(types.late(() => ItemModel)) }), {}),
}).props({
count: types.number
});
export interface RootStoreType extends Instance<typeof RootStore> {}
// ItemModel.ts
import type { RootStoreType } from './RootStore';
export const ItemModel = types.model('ItemModel', {
id: types.identifier,
description: types.string,
created: types.Date,
count: types.number,
}).views(self => ({
get rootStore(): RootStoreType { // typing the return type explictly is what makes this work
const queryClient = getEnv(self).queryClient;
return queryClient.rootStore;
},
get computeValue(): number { // also need to explictly type values that derive from rootStore
return this.rootStore.count + self.count;
}
}));
I recently came across this problem when I'm writing my computed value. Consider the following example,
In some model,
In 'contexts/StoreContext':
In this function, I want to get the rootStore using the
getQueryClient
. ThequeryClient
is created in a separate file, which is imported to this file. The RootStoreModel is created using thecreateRootStore
. Now, there is a circular dependency issue, since theSomeModelBase
is part ofRootStoreModel
andSomeModelBase
import from the StoreContext file to get thegetQueryClient
.Of course, if you define all the models in a single file, it won't be an issue. But for large project with many models this is obviously not ideal.
I currently can get around this issue using the native
getEnv
like this:But doing so I lose typing. Any idea how I can solve this problem?