我正在尝试实现一个函数,该函数将由不同元素组成的数组拆分为某种类型的元素的数组(在函数调用中指定)。这是简化的代码:
export enum GenericElementType {
ONE = 'type one',
TWO = 'type two'
}
export interface TypeA {
id: string;
type: GenericElementType.ONE;
}
export interface TypeB {
id: string;
type: GenericElementType.TWO;
}
export type ElementType = TypeA | TypeB;
const arrayOfElements: (DFDElementType)[] = [];
function filterElementsOfCertainType<T extends ElementType>
(elements: (ElementType)[], type: GenericElementType): T[] {
return elements.filter((element: ElementType) => element.genericType === type);
}
这将导致错误,因为并非ElementType
中的每个元素都与返回类型T
相匹配。我将如何实现正确键入的此功能?
这是一个Playground链接。
另一个Playground link使用通用类型。
答案 0 :(得分:1)
假设您提供的是“特定类型”,返回ElementType [],然后将element.type与type进行比较。认为应该起作用。干杯
编辑:
我认为您应该想到这种模式。从您的最后一个操场。 elementOfTypeA:TypeA []应该是elementOfTypeA:ElementType [],您已经提供了所需的类型作为参数。用简单的逻辑来说,这永远行不通:
interface person{
id: string;
}
type teacher = person | number;
const randomVariable: person = 3;
尽管如此,这将:
interface person{
id: string;
}
type teacher = person | number;
const randomVariable: teacher = 3;
最后一招:
function filterElementsOfCertainType<T extends ElementType>
(elements: any[], type: GenericElementType): T[] {
return elements.filter((element: T) => element.type !== undefined && element.type === type);
}
然后const elementOfTypeA:TypeA [] = filterElementsOfCertainType([a,b,c],GenericElementType.TWO);将工作。
这似乎也是打字稿文档希望您这样做的方式。 https://www.typescriptlang.org/docs/handbook/advanced-types.html
选中“用户定义的类型防护”。干杯。
答案 1 :(得分:0)
此playground应该有效。但是,这是正确的输入:
function filterElementsOfCertainType<T extends ElementType>
(elements: T[], type: GenericElementType): T[] {
return elements.filter((element: T) => element.type === type);
}