如何指定一种过滤某种类型元素的数组的方法?

时间:2019-05-09 13:19:06

标签: typescript typescript-typings

我正在尝试实现一个函数,该函数将由不同元素组成的数组拆分为某种类型的元素的数组(在函数调用中指定)。这是简化的代码:

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使用通用类型。

2 个答案:

答案 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

选中“用户定义的类型防护”。干杯。

playground

答案 1 :(得分:0)

playground应该有效。但是,这是正确的输入:

function filterElementsOfCertainType<T extends ElementType>
  (elements: T[], type: GenericElementType): T[] {
  return elements.filter((element: T) => element.type === type);
}