Typescript 击败阵列<;T>;和IObservableArray<;T>;不相容

Typescript 击败阵列<;T>;和IObservableArray<;T>;不相容,typescript,types,mobx,mobx-react,Typescript,Types,Mobx,Mobx React,假设我的存储中有一个属性,它是某种类型的数组MyType,并用observable修饰: class MyStore { @observable array } 我知道在正常情况下,这应该是一个数组。但当我这样宣布的时候 class MyStore { @observable array: Array<MyType> } 然后我就失去了合法地为这个道具分配数组值的可能性(在合法的情况下,我的意思是分配而不构造…因为IObservableArray-这个方法的缺点太

假设我的存储中有一个属性,它是某种类型的数组
MyType
,并用observable修饰:

class MyStore {
    @observable array
}
我知道在正常情况下,这应该是一个
数组
。但当我这样宣布的时候

class MyStore {
    @observable array: Array<MyType>
}
然后我就失去了合法地为这个道具分配
数组
值的可能性(在合法的情况下,我的意思是分配而不构造
…因为IObservableArray
-这个方法的缺点太明显了:很多不必要的代码,无论何时使用类型都应该导入,等等)

我还尝试使用并集和相交类型:

  • 交叉点(
    Array&IObservableArray
    )在将
    Array
    值分配给此属性时产生错误:
    类型MyType中缺少属性“SpiceWithArray”
  • 联合(
    Array | IObservableArray
    )仍然会导致方法的丢失
    。删除(项目:MyType)
  • 我是否遗漏了什么或误解了什么?有什么合法的方法可以打败它吗?提前谢谢大家



    顺便说一句,我使用的
    mobx
    版本是
    4
    ,因为我需要支持旧的iPad,不幸的是

    创建您自己定制的类型,扩展数组类,手动实现IObservableArray方法作为可选方法怎么样

    既然你被锁定在mobx@4.6.0,随着版本的提高,维护界面并没有问题

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

    我调用类型MyExtendedObjectableArray

    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
    }
    
    从“mobx”导入{IArrayChange,IArraySplice,IArrayWillChange,IArrayWillSplice,IInterceptor,IObservableArray,Lambda,observable};
    接口MyExtendedObservableArray扩展数组{
    拼接WithArray?(索引:number,deleteCount?:number,newItems?:T[]):T[];
    观察?(监听器:(changeData:IArrayChange | IArraySplice)=>void,firestimmediate?:布尔):Lambda;
    拦截?(处理程序:IInterceptor):Lambda;
    清晰?():T[];
    peek?():T[];
    替换?(新项:T[]):T[];
    find?(谓词:(项:T,索引:number,数组:IObservableArray)=>boolean,thisArg?:any,fromIndex?:number):T |未定义;
    findIndex?(谓词:(item:T,index:number,array:IObservableArray)=>boolean,thisArg?:any,fromIndex?:number):number;
    移除?(值:T):布尔值;
    移动?(从索引:编号,到索引:编号):无效;
    toJS?():T[];
    toJSON?():T[];
    }
    类MyType{}
    让myType=新的myType();
    类MyStore{
    @可观察数组:MyExtendedObservableArray=[myType]
    //没有TSC编译错误
    }
    
    您需要使用下一个语法,这不会生成任何TS错误。您可以安全地使用
    Array
    IObservableArray

    classmystore{
    只读数组=可观察([])
    @行动
    getItems(){
    然后((response)=>this.array.replace(response.data));
    }
    @行动
    removeItem(项目:MyType){
    此.array.remove(项);
    }
    }
    
    只读-因为您通常不打算为
    数组
    属性执行赋值,例如
    this.array=itemsFromServer


    替换、删除-IObservableArray的方法

    不错的解决方案,但是这个接口也应该被导入,在这种情况下,从
    mobx
    导入
    IObservableArray
    更容易,然后只需将其指定为
    this.someObservableArray=someArray作为IObservableArray
    。不幸的是,您提供的解决方案并不能解决使用方便的主要问题(@levitationmbalance我不确定我是否理解。在我的解决方案中,您不需要导入任何东西。MyExtendedObservableArray具有IObservableArray和Array的所有方法。因此,分配一个常规数组就足够了,您将在其上拥有mobx方法,而无需导入或使用“as…”符号。你唯一需要导入它的地方是类定义中的一次(我认为这是你无论如何都无法避免的)哦,sry,我误解了你。那么,这似乎是解决问题的唯一方法。这并不像我希望的那样方便,但似乎很有效)谢谢你的回答!太好了!谢谢:)没有注意到这个
    replace
    方法,它在这种情况下非常有用
    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
    }