typescript - 基于模板参数访问 Typescript 对象属性
问题描述
我想创建一个按字段查找项目的 Typescript Collection 类,如下所示:
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 中是否可行?
解决方案
您需要K
在运行时的某个地方传递一个类型的值才能使其工作。如果我正确理解您的Collection
课程的要点,您将需要一个实际的数组T
和 type 的值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
好的,希望有帮助。祝你好运!
推荐阅读
- elasticsearch - elasticsearch节点不活跃
- google-sheets - 从工作表 1 中的单元格中调用工作表名称以从具有自定义名称的工作表中调用数据
- nginx - 不要写端口并添加应用程序名称以进行远程访问
- javascript - JSON API 返回未定义
- c# - 创建插入操作,但是在从 Model StudentView -> Student 转换并传递到 InsertStudentAsync 之后,函数返回 null
- python - 在这门课上我可以做得更好吗?Python 类重构
- bash - 如何在某些特定符号后的字符之间插入空格?
- node.js - 新创建项目的 sam local 调用超时(通过 sam init 创建)
- amazon-quicksight - QuickSight 仪表板中的动态文本字段
- javascript - EJS没有安装