带有RxJS过滤器打字问题的打字稿

时间:2019-07-25 16:57:06

标签: angular typescript rxjs ngrx

我刚刚从打字稿2.4升级到3.2,现在使用未知类型,类型系统更严格,会触发一些我以前没有的错误。

因此,我的作用是从存储中检索一些可能为空的数据,并且我想在分派下一个操作之前通过使用过滤器确保其不为空。

@Effect() saveSuccess$: Observable<Action> = this.actions$.pipe(
        ofType(actions.SAVE_SUCCESS),
        switchMapTo(this.store.pipe(select(selectors.getId))),
        filter((id: number | null) => id !== null),
        map((id: number) => new actions.GetData({ Id }))
);

过滤器现在变成红色:

    Argument of type 'MonoTypeOperatorFunction<number | null>' is not assignable to parameter of type 'OperatorFunction<number | null, number>'.
  Type 'Observable<number | null>' is not assignable to type 'Observable<number>'.
    Type 'number | null' is not assignable to type 'number'.
      Type 'null' is not assignable to type 'number'.ts(2345)

我可以使用任何类型来绕过错误,但是我觉得不应该这样做。如果我将地图更改为接受number | null,则可以使用,但由于它正是过滤器的工作,因此没有任何意义。

1 个答案:

答案 0 :(得分:2)

尝试通过添加返回类型id is number将过滤器功能转换为类型防护。我知道这在过滤数组时有效,尽管我没有用可观察对象进行测试,但我希望它也可以在这里工作(因为它们用this type definition定义了filter):

this.actions$.pipe(
  ofType(DCFActions.SAVE_SUCCESS),
  switchMapTo(this.store.pipe(select(selectors.getId))),
  filter((id: number | null): id is number => id !== null),
  map((id: number) => new actions.GetData({ Id }))
);

如果您想创建更通用的过滤器功能以从更多的东西中过滤出空值,而不仅仅是数字,那么您可以这样编写:

const notNull = <T>(value: T | null): value is T => value !== null;

// ... to be used like:
filter(notNull);

您可以在此处了解有关用户定义的类型防护的更多信息:https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards