克服 Array<T> 和 IObservableArray<T> 的不兼容性
Defeating the Array<T> and IObservableArray<T> incompatibility
假设我的商店中有一些 属性 是某种类型的数组 MyType
和 decorated with observable:
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>
值的可能性(在 合法 我的意思是分配没有构造 ... as IObservableArray<MyType>
- 这个的缺点方法太明显:很多不必要的代码,类型应该在使用时导入等)
我也尝试过使用并集和交集类型:
- 交集 (
Array<MyType> & IObservableArray<MyType>
) 在为该道具分配 Array<MyType>
值期间产生错误:Property 'spliceWithArray' is missing in type MyType
.
- Union (
Array<MyType> | IObservableArray<MyType>
) 仍然导致方法丢失 .remove(item: MyType)
.
我是否遗漏或误解了什么?有什么合法的方法可以打败它吗?提前谢谢大家!
顺便说一句,我使用的mobx
版本是4
,因为我需要支持旧iPad,不幸的是
如何创建您自己的定制类型、扩展 Array class 并手动实现 IObservableArray 方法作为可选方法?
既然锁定了mobx@4.6.0,随着版本的升级,界面的维护没有问题。
这并不理想,但这是我能想到的唯一方法,它允许您分配数组并使用 .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
}
您需要使用下一个语法,这不会产生任何 TS 错误。您可以安全地使用 Array
和 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 - 因为你大多不打算为 array
属性 做作业,比如 this.array = itemsFromServer
替换、移除 - IObservableArray
的方法
假设我的商店中有一些 属性 是某种类型的数组 MyType
和 decorated with observable:
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>
值的可能性(在 合法 我的意思是分配没有构造 ... as IObservableArray<MyType>
- 这个的缺点方法太明显:很多不必要的代码,类型应该在使用时导入等)
我也尝试过使用并集和交集类型:
- 交集 (
Array<MyType> & IObservableArray<MyType>
) 在为该道具分配Array<MyType>
值期间产生错误:Property 'spliceWithArray' is missing in type MyType
. - Union (
Array<MyType> | IObservableArray<MyType>
) 仍然导致方法丢失.remove(item: MyType)
.
我是否遗漏或误解了什么?有什么合法的方法可以打败它吗?提前谢谢大家!
顺便说一句,我使用的mobx
版本是4
,因为我需要支持旧iPad,不幸的是
如何创建您自己的定制类型、扩展 Array class 并手动实现 IObservableArray 方法作为可选方法?
既然锁定了mobx@4.6.0,随着版本的升级,界面的维护没有问题。
这并不理想,但这是我能想到的唯一方法,它允许您分配数组并使用 .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
}
您需要使用下一个语法,这不会产生任何 TS 错误。您可以安全地使用 Array
和 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 - 因为你大多不打算为 array
属性 做作业,比如 this.array = itemsFromServer
替换、移除 - IObservableArray
的方法