我想创建一个Typescript集合类,该类按字段查找项目,如下所示:
class Collection<T, K keyof T> {
private _items: T[];
public isItemInCollection(item: T) {
return _items.find((a) => a[K] === item[K], this._items) !== undefined;
}
}
然后我想用类似这样的实例化它:
interface MyItem {
idField: string,
otherField: number,
}
class ItemCollection: MyCollection<MyItem, 'idField'> { }
不幸的是,这行不通,我在引用item[K]
之类的错误消息中说K是类型而不是值。我了解导致错误的原因,但我不知道该如何解决。在Typescript中甚至有可能吗?
答案 0 :(得分:2)
您需要在运行时的某个地方传递类型为K
的值,此功能才能起作用。如果我正确理解了Collection
类的要点,则将需要一个T
的实际数组和一个K
类型的值。获得这些值的一个好地方是在构造新的Collection
实例时。也就是说,使构造函数将其作为参数:
class Collection<T, K extends keyof T> {
private _items: T[];
private _idKey: K;
constructor(items: T[], idKey: K) {
this._items = items;
this._idKey = idKey;
}
public isItemInCollection(item: T) {
return (
this._items.find(a => a[this._idKey] === item[this._idKey]) !== undefined
);
}
}
然后,您可以按预期使用它(我想是这样,无论如何……您实际上并没有显示用例)。给定这些类型和对象:
interface MyItem {
idField: string;
otherField: number;
}
const itemA: MyItem = { idField: "A", otherField: 1 };
const itemB: MyItem = { idField: "B", otherField: 2 };
const itemC: MyItem = { idField: "C", otherField: 3 };
const items: MyItem[] = [itemA, itemB];
您可以构造一个新的Collection
:
const itemCollection = new Collection(items, "idField");
通过类型推断,itemCollection
的类型为Collection<MyItem, "idField">
。并使用它:
console.log(itemCollection.isItemInCollection(itemA)); // true
console.log(itemCollection.isItemInCollection(itemC)); // false
console.log(
itemCollection.isItemInCollection({ idField: "A", otherField: 2893 })
); // true so be careful
好的,希望能有所帮助。祝你好运!