我正在try 创建一个泛型TypeScript函数,该函数递归地通过树 struct 查找具有特定id值的项.为了使其可重用,我try 使用泛型,您只需为函数提供顶级、id值以及用于id和子级的属性名称.下面是我的示例课程:
export class Thing{
name: string;
id: string;
children: Thing[];
constructor(){
this.name='';
this.id='';
this.children=[];
}
}
以及按id查找项目的方法:
export function GetGenericItemById<T>(
allItems: T[],
idField: keyof T,
childrenField: keyof T,
id: string
): any {
const item = allItems.find((x) => x[idField] === id);
if (item != null) {
return item;
}
const subItems = allItems.flatMap((i) => i[childrenField]);
if (subItems.length === 0) {
return undefined;
}
return GetGenericItemById(subItems, idField, childrenField, id);
}
然而,在find函数中,它进行比较x[idField] === id
,它告诉我This condition will always return 'false' since the types 'T[keyof T]' and 'string' have no overlap.
.这里的目的是从对象中获取该属性并获取其值.我做错了什么?
我做这件事时没有像这样的泛型:
export function GetGenericItemById(
allItems: any[],
idField: string,
childrenField: string,
id: string
): any {
const item = allItems.find((x) => x[idField] === id);
if (item != null) {
return item;
}
const subItems = allItems.flatMap((i) => i[childrenField]);
if (subItems.length === 0) {
return undefined;
}
return GetGenericItemById(subItems, idField, childrenField, id);
}
这是可行的,但是你也可以把你想要的任何东西放入idField
和childrenField
属性中,这样你就可以很容易地把它搞砸.最好将这些密钥限制为您正在使用的类型的有效密钥.我以为我在上面的try 是这样做的,但它似乎不一样,因为它给出了那个错误.
EDIT
这里的每个请求都是我打算如何使用它的一个简单示例.假设我有一个简单的数据 struct ,其中包含"things".每个Thing
人都有一个id和一个名字,以及其他Thing
人的潜在子女.这样地:
const data=[
{
name: "thing 1",
id: "1",
children: [
{
name: "thing 1a",
id: "1a",
children: []
}
]
},
{
name: "thing 2",
id: "2",
children: [
{
name: "thing 2a",
id: "2a",
children: []
}
]
}
];
我的意图是将函数称为这样的函数:
const foundThing = GetGenericItemById<Thing>(topThings, 'id', 'children', '1a');
在本例中,topThings
将是一个只包含顶级项(示例数据中的ID 1和ID 2)的集合.基本上,它只是在树下搜索以找到该项目.我希望foundThing
是id为"1a"的Thing
对象.
EDIT
你真的不应该把<Thing>
部分放进go ,因为第一个论点暗示了这一点,但为了清楚起见,我把它放在这里.