我有一个由ChildA
和ChildB
扩展的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);