Search code examples
typescripttypesmobxmobx-react

Defeating the Array<T> and IObservableArray<T> incompatibility


Assume I have some property in my store that is being array of some type MyType and decorated with observable:

class MyStore {
    @observable array
}

I know that in normal world this should be an Array<MyType>. But when I'm declaring it in this way,

class MyStore {
    @observable array: Array<MyType>
}

then I lose the method .remove(item: MyType). On the other hand, if I'm declaring it with IObservableArray<MyType>,

class MyStore {
    @observable array: IObservableArray<MyType>
}

then I lose a possibility to legally assign an Array<MyType> values to this prop (under legally I mean assigning without construction ... as IObservableArray<MyType> - disadvantages of this method are too obvious: a lot of unnecessary code, the type should be imported whenever it used, etc.)

I also tried to use union and intersection types:

  1. Intersection (Array<MyType> & IObservableArray<MyType>) produces an error during assigning an Array<MyType> value to this prop: Property 'spliceWithArray' is missing in type MyType.
  2. Union (Array<MyType> | IObservableArray<MyType>) still causes lost of method .remove(item: MyType).

Am I missing or misunderstanding something? Is there any legal way to defeat it? Thank you all in advance!


By the way, the mobx version I'm using is 4, because it is necessary for me to support old iPads, unfortunately


Solution

  • You need to use the next syntax, this won't generate any TS errors. And you can safely use methods of both Array and IObservableArray

    class MyStore {
      readonly array = observable<MyType>([])
    
      @action
      getItems() {
        api.getItems<MyType[]>().then((response) => this.array.replace(response.data));
      }
    
      @action
      removeItem(item: MyType) {
        this.array.remove(item);
      }
    }
    

    readonly - as you are mostly not intended to do an assignment for array property, like this.array = itemsFromServer

    replace, remove - methods of IObservableArray