带有 RxJS 过滤器输入问题的 Typescript
Posted
技术标签:
【中文标题】带有 RxJS 过滤器输入问题的 Typescript【英文标题】:Typescript with RxJS filter typing problem 【发布时间】:2019-12-04 00:34:04 【问题描述】:我刚刚从 typescript 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】:尝试通过添加返回类型id is number
将您的过滤器函数转换为类型保护。我知道这在过滤数组时有效,虽然我没有用 observables 测试它,但我希望它也可以在那里工作(因为他们用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
【讨论】:
如果类型(此处:数字)未知,您也可以内联所有这些:filter(<T>(x: T | null): x is T => x !== null)
我真的很喜欢这个解决方案。太好了!
notNull
实用功能很棒。谢谢。以上是关于带有 RxJS 过滤器输入问题的 Typescript的主要内容,如果未能解决你的问题,请参考以下文章
在使用带有 Angular 的 FromEvent RxJS 订阅输入标签值更改时如何避免使用“任何”?