击败Array <t>和IObservableArray <t>不兼容

时间:2018-11-27 12:25:34

标签: typescript types mobx mobx-react

假设我的商店中有一些属性,该属性是MyType类型的数组,并且装饰且具有可观察性:

class MyStore {
    @observable array
}

我知道,在正常情况下,这应该是Array<MyType>。但是当我以这种方式声明时,

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

然后我丢失了方法.remove(item: MyType)。另一方面,如果我使用IObservableArray<MyType>进行声明,则

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

然后,我将无法合法地为此道具分配一个Array<MyType>值(在 legally 下,我的意思是没有构造... as IObservableArray<MyType>进行分配-这种方法的缺点太明显了:很多不必要的代码,应在每次使用该类型时将其导入,等等。

我还尝试使用联合和交叉点类型:

  1. 交集(Array<MyType> & IObservableArray<MyType>)在为此道具分配Array<MyType>Property 'spliceWithArray' is missing in type MyType时产生错误。
  2. 联合(Array<MyType> | IObservableArray<MyType>)仍然导致方法.remove(item: MyType)丢失。

我丢失或误解了什么吗?有什么合法的方法可以击败它吗?预先谢谢大家!


顺便说一句,我正在使用的mobx版本是4,很不幸,因为我必须支持旧的iPad,

2 个答案:

答案 0 :(得分:1)

如何创建自己的定制类型,扩展Array类以及手动将IObservableArray方法实现为可选方法?

由于您被锁定为mobx@4.6.0,因此随着版本的升级,维护界面没有问题。

这并不理想,但这是我能想到的唯一方法,它允许您分配Array并使用.remove()之类的方法。

我将类型称为 MyExtendedObservableArray

import {IArrayChange, IArraySplice, IArrayWillChange, IArrayWillSplice, IInterceptor, IObservableArray, Lambda, observable} from "mobx";

interface MyExtendedObservableArray<T> extends Array<T>{
    spliceWithArray?(index: number, deleteCount?: number, newItems?: T[]): T[];
    observe?(listener: (changeData: IArrayChange<T> | IArraySplice<T>) => void, fireImmediately?: boolean): Lambda;
    intercept?(handler: IInterceptor<IArrayWillChange<T> | IArrayWillSplice<T>>): Lambda;
    clear?(): T[];
    peek?(): T[];
    replace?(newItems: T[]): T[];
    find?(predicate: (item: T, index: number, array: IObservableArray<T>) => boolean, thisArg?: any, fromIndex?: number): T | undefined;
    findIndex?(predicate: (item: T, index: number, array: IObservableArray<T>) => boolean, thisArg?: any, fromIndex?: number): number;
    remove?(value: T): boolean;
    move?(fromIndex: number, toIndex: number): void;
    toJS?(): T[];
    toJSON?(): T[];
}

class MyType{}
let myType = new MyType();

class MyStore {
    @observable array: MyExtendedObservableArray<MyType> = [myType] 
    // no TSC compilation error
}

答案 1 :(得分:1)

您需要使用下一种语法,这不会产生任何TS错误。而且,您可以安全地使用ArrayIObservableArray的方法

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);
  }
}

只读-因为您通常不打算为array属性进行赋值,例如this.array = itemsFromServer

替换,删除-IObservableArray的方法