Reputation: 301
I'm trying to implement a function which splits an array consisting of different elements into an array of elements of a certain type (specified in the function call). This is the simplified code:
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);
}
This results in an error, because not every element in ElementType
matches the return type T
. How would I go about implementing this function correctly typed?
Here is a Playground link.
Another Playground link using generic typing.
Upvotes: 0
Views: 77
Reputation: 124
Assuming your "specific types" are the ones you gave, returning ElementType[], and compare the element.type with type. Think that should work. Cheers
Edit:
I think you should think of the pattern. From your last playground. elementOfTypeA: TypeA[] should be elementOfTypeA: ElementType[], you already give the required type as parameter. To put it in simpler logic, this will never work:
interface person{
id: string;
}
type teacher = person | number;
const randomVariable: person = 3;
although, this will:
interface person{
id: string;
}
type teacher = person | number;
const randomVariable: teacher = 3;
last resort:
function filterElementsOfCertainType<T extends ElementType>
(elements: any[], type: GenericElementType): T[] {
return elements.filter((element: T) => element.type !== undefined && element.type === type);
}
then const elementOfTypeA: TypeA[] = filterElementsOfCertainType([a, b, c], GenericElementType.TWO); will work.
it also seems to be the way the typescript documentation wants you to do it. https://www.typescriptlang.org/docs/handbook/advanced-types.html
check "User-Defined Type Guards". Cheers mate.
Upvotes: 1
Reputation: 2633
This playground should work. However, this is the correct typing:
function filterElementsOfCertainType<T extends ElementType>
(elements: T[], type: GenericElementType): T[] {
return elements.filter((element: T) => element.type === type);
}
Upvotes: 0