mobx-state-tree icon indicating copy to clipboard operation
mobx-state-tree copied to clipboard

Typing "self" when splitting actions into multiple files

Open evelant opened this issue 5 years ago • 3 comments

  • [ X ] I've checked documentation and searched for existing issues
  • [ X ] I tried the spectrum channel

To better organize my code I'd like to put some action definitions in multiple files. An issue arises with typing "self" when doing this. For example:

File1.ts

import OtherActions from "./file2"
export const MyModel = t.model({foo: t.string}).actions(self => ({
    typeOfSelfIsFineHere(){
          ....
    }
})).actions(OtherActions)

File2.ts

import {MyModel} from "./file1"

//TS error 2502 'self' is referenced directly or indirectly in its own type annotation
export default (self: Instance<typeof MyModel>) => ({
    typeOfSelfIsErrorHere(){
       ....
    }
})

I'm unable to provide the proper type for "self" when trying to write actions in a separate file because it results in a circular type definition. Any thoughts on how to work around this?

Spectrum question link: https://spectrum.chat/mobx-state-tree/general/typing-self-when-splitting-actions-into-multiple-files~7ab0ccdb-24b2-49bb-a8c0-8462d3aac07e

evelant avatar Jun 19 '19 19:06 evelant

+1 I have the same problem when I tried move actions and views to separated files.

alex-pol avatar Jun 25 '19 10:06 alex-pol

In your case, you can break the type in two (this works exactly the same technically), and grab the type of the partial type:

File 1

import OtherActions from "./file2"
export const MyBaseModel = t.model({foo: t.string}).actions(self => ({
    typeOfSelfIsFineHere(){
          ....
    }
}))

export const MyModel = MyBaseModel.actions(OtherActions)

File 2

import {MyBaseModel} from "./file1"

export default (self: Instance<typeof MyBaseModel>) => ({
    typeOfSelfIsErrorHere(){
       ....
    }
})

See also the readme section: https://github.com/mobxjs/mobx-state-tree#typing-self-in-actions-and-views

mweststrate avatar Jul 19 '19 19:07 mweststrate

Now over a year later I've got an 8k line file making up my root MST store and I'm finally getting to attempting splitting it into smaller chunks. Everything has stayed in one file so far because it's easier, but it's starting to be a drain on editor performance.

The technique above works but it gets a bit messy when actions depend upon each other. Any action that calls another action must either be in the same file or yet another name needs to be introduced to hold the state of the partially built store. Unfortunately I don't really see any way around this, anybody have ideas?

evelant avatar Sep 02 '20 01:09 evelant

This solved my problem (I believe).

File1.ts

import OtherActions from "./file2"
export const MyModel = t.model({foo: t.string}).actions(self => ({
    typeOfSelfIsFineHere(){
          ....
    }
})).actions(OtherActions)

File2.ts

export default  <T extends IStateTreeNode>(mstInstance: T) => {
  const self = mstInstance as unknown as Instance<typeof MyModel>
  return {
    typeOfSelfIsErrorHere() {
      // do something
    },
  }
}

EndyZhou avatar Feb 08 '23 05:02 EndyZhou

Hey folks,

This MobX-State-Tree issue is pretty old, and looks like there were some satisfactory answers already.

I'm gonna go ahead and close this out. Thanks for your time!

coolsoftwaretyler avatar Nov 29 '23 06:11 coolsoftwaretyler