如何创建一个泛型筛选器,返回泛型<T>中传递的数组元素



我有一个由ChildAChildB扩展的Parent接口;

interface Parent {
sharedProp: string,
}
interface ChildA extends Parent { 
onlyInA: string,
}
interface ChildB extends Parent { 
onlyInB: number
}

我有一个包含联合数组类型的数组:

const entities: (ChildA|ChildB)[] = [
{
sharedProp: "this will be B",
onlyInA: "because Im a"
}, {
sharedProp: "this will be B",
onlyInB: 12345
}
]

我做了一个非通用函数,可以做我想要的:

const childrenWithCertainSharedProp = (sharedProp: string): ChildA[] => {
return entities
.filter(isChildA)
.filter(e => e.sharedProp === sharedProp);
}

我可以做console.log(childrenWithCertainSharedProp('xxx'));

这是一个演示。

但正如你所看到的,我把返回作为ChildA[],我可以用ChildB[]做同样的事情。

我想要一些类似于以下的东西,但我无法做到:

const childrenWithCertainSharedProp = <T>(sharedProp: string): T[] => {
return entities
.filter(/* filter depending on T */)
.filter(e => e.sharedProp === sharedProp);
}

基本上,我想要的是以某种方式通用地键入guard,以确保如果我通过<ChildA>,我将确保它只过滤ChildA等等

您还需要至少传递一个具有类型的参数,因为在运行时typescript无法访问类型params。

作为警告,这只会和你的typeGuards一样好。

const childrenWithCertainSharedProp = <T extends ChildA | ChildB>(arr: T[], sharedProp: string): T[] => {
return arr.filter(e => e.sharedProp === sharedProp);
}
console.log(childrenWithCertainSharedProp(entities.filter(isChildA), 'xxx')[0].onlyInA);
console.log(childrenWithCertainSharedProp(entities.filter(isChildB), 'xxx')[0].onlyInB);

最新更新