14

I have this basic model.

const stuff = types.model({
  term: types.string,
  excludeTerm: types.string,
  stores: types.array(types.string)
}).actions(self => ({
  setTerm(term: string) {
    self.term = term
  },
  setExcludeTerm(term: string) {
    self.excludeTerm = term
  },
  setStores(stores: string[]) {
    self.stores = stores   // <<< the lint error is on this line
  }
}))

I get the following TS Lint error:

Type 'string[]' is not assignable to type 'IMSTArray<ISimpleType> & IStateTreeNode<IArrayType<ISimpleType>>'. Type 'string[]' is missing the following properties from type 'IMSTArray<ISimpleType>': spliceWithArray, observe, intercept, clear, and 4 more.ts(2322)

This is an annoying error. I can fix it by assigning like this: (self as any).stores = stores but I want to stop doing hacks to my code.

The question is why I get this error? Is there another way to assign to an array type in mobx-state-tree?

I couldn't find in mobx-state-tree a more detailed documenation for working with arrays. Does anyone know any?

ataravati
  • 8,159
  • 5
  • 47
  • 70
etudor
  • 823
  • 9
  • 17

3 Answers3

28

The solution is to use cast:

import { cast } from "mobx-state-tree"

// .....

self.stores = cast(stores)

This is because MST enables snapshots to be assigned to actual values, and automatically converts them. This doesn't just apply to arrays, but to all types of values. However, typescript doesn't have support for an assignment to be more narrow that the thing it is being assigned to, which is the reason the cast is needed. cast doesn't do anything, but it helps TS to figure out that this assignment is valid

tuan.tran
  • 1,548
  • 12
  • 19
mweststrate
  • 4,547
  • 1
  • 14
  • 22
3

You can use self.stores.replace(stores)

Here are the docs for MST, these are really the only docs I have seen out there: https://github.com/mobxjs/mobx-state-tree

There is also a function setLivelinessCheck('error') that helps a lot with debugging locally to see errors that may occur. It is in the list of API Overview functions: https://github.com/mobxjs/mobx-state-tree#api-overview

Nicholas Pesa
  • 1,906
  • 2
  • 22
  • 37
  • Thanks. Where can I find the available methods on MST arrays? Are there any docs? – etudor Apr 30 '19 at 11:34
  • I recently had another error where pushing a new value to a volatile array was not triggering react to update so I really think some docs would be useful. – etudor Apr 30 '19 at 11:35
  • I have updated my answer with the docs. For the react updating after a change in the tree, how are you using this with your react components? Are you using a `Provider` and the mobx-react packages `observer`? – Nicholas Pesa Apr 30 '19 at 20:35
2

Array in MST is not a usual array, it's a complex type - IMSTArray<ISimpleType<string>>, so TS lint error that you get is fully expected. In my opinion though, it is definitely not intuitively justified (and frightening for newcomers).

The way you solve it is not a hack, but I'd say the only simple way around it.

jayarjo
  • 14,000
  • 20
  • 83
  • 123