Typescript 保护函数的泛型类型

Typescript 保护函数的泛型类型,typescript,typescript-generics,Typescript,Typescript Generics,我想创建一个函数,将两种类型的列表过滤成两个单独的唯一类型列表。我成功地用硬编码类型创建了它: interface TypeA { kind: 'typeA'; } interface TypeB { kind: 'typeB'; } filterMixedList(mixedList$: Observable<(TypeA | TypeB)[]>): Observable<TypeA[]> { return mixedList$.pipe( map(

我想创建一个函数,将两种类型的列表过滤成两个单独的唯一类型列表。我成功地用硬编码类型创建了它:

interface TypeA {
  kind: 'typeA';
}
interface TypeB {
  kind: 'typeB';
}
filterMixedList(mixedList$: Observable<(TypeA | TypeB)[]>): Observable<TypeA[]> {
  return mixedList$.pipe(
    map(items => items
      .filter((item): item is TypeA => item.kind === 'typeA')),
  );
}
接口类型A{
种类:A型;
}
接口类型B{
种类:B型;
}
filterMixedList(mixedList$:可观察):可观察{
返回mixedList$.pipe(
映射(项目=>items
.filter((项目):项目为TypeA=>item.kind=='TypeA')),
);
}
但有没有办法创建泛型以避免硬编码?请帮忙

PS:以下是最小可重复性示例:

使其通用的一种方法是传入type guard函数。看起来是这样的:

function typeFromMixedList<T, U extends T>(
  mixedList$: Observable<T[]>,
  guard: (item: T) => item is U
): Observable<U[]> {
  return mixedList$.pipe(map(items => items.filter(guard)));
}
好吧,希望这会有帮助;祝你好运


泛型能否依赖
种类
属性?如果没有,它是如何区分的?两种类型都有,但它如何与泛型或类型保护连接我不知道。。。简单的泛型对我来说很清楚,但是使用类型guard-太复杂了(PS:非常感谢所有关于这一点的文档。抱歉,也许我的问题不清楚。这个问题的解决方案是否可以假设泛型函数将仅用于具有区分它们的
种类
属性的类型?类型保护仅用于缩小TS在编译时知道的类型。但是,在您的情况下,您需要测试吗这将在运行时检查类型。此时类型系统不存在,因此您只能硬编码这些类型或将这些类型具体化为更具体的类或变量。有一种方法可以将其泛化,但我的环境中没有您的依赖项;您能编辑此代码以形成一个在独立IDE中工作的或者提供一个到配置了相关依赖项的web IDE的链接?不容易从
rxjs/operators
导入,所以我
function typeFromDiscriminatedUnionList<
  T,
  K extends keyof T,
  V extends (T[K]) & (string | number | undefined | null)
>(
  mixedList$: Observable<T[]>,
  key: K,
  val: V
): Observable<Extract<T, { [P in K]?: V }>[]> {
  return mixedList$.pipe(
    map(items =>
      items.filter(
        (item): item is Extract<T, { [P in K]?: V }> => item[key] === val
      )
    )
  );
}
typeFromMixedList(of([a, b]), (x): x is TypeA => x.kind === "typeA").subscribe(
  v => (dataDivA.innerHTML = JSON.stringify(v))
);

typeFromDiscriminatedUnionList(of([a, b]), "kind", "typeB").subscribe(
  v => (dataDivB.innerHTML = JSON.stringify(v))
);