简体   繁体   English

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

[英]Typescript with RxJS filter typing problem

I've just upgraded from typescript 2.4 to 3.2 and now with the unknown type, the type system is stricter which trigger some errors that I didn't have before. 我刚刚从Typescript 2.4升级到3.2,现在使用未知类型,类型系统更加严格,会触发一些我以前没有的错误。

So I have an effect that retreive some possibly null data from the store and I want to make sure its not null by using a filter before dispatching my next action. 因此,我的作用是从存储中检索一些可能为空的数据,并且我想在分派下一个操作之前通过使用过滤器确保其不为空。

@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 }))
);

The filter is now red saying: 过滤器现在显示为红色:

    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)

I can bypass the error by using any type but I feel like I shouldn't. 我可以使用任何类型来绕过错误,但是我觉得不应该这样做。 If I change the map to accept number | null 如果我更改地图以接受number | null number | null it works but it makes no sens since its exactly the filter's job. number | null它可以工作,但由于它正是过滤器的工作,因此没有任何意义。

Try turning your filter function into a type guard by adding the return type id is number . 尝试通过添加返回类型id is number来将过滤器功能转变为类型防护。 I know this works when filtering arrays, and while i havn't tested it with observables i expect it would work there too (because they define filter with 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 }))
);

If you wanted to make a more general filter function to filter out nulls from more things than just numbers, then you could write that like this: 如果您想创建一个更通用的过滤器功能以从更多的东西中过滤出空值,而不仅仅是数字,那么您可以这样编写:

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

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

You can read more about user-defined type guards here: https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards 您可以在此处阅读有关用户定义类型防护的更多信息: https : //www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM