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
}