combineLatestWith调用pipe报错:Property 'pipe'不存在于OperatorFunction类型
combineLatestWith无法使用pipe操作符的原因及解决方法
问题描述
之前项目中使用combineLatest一切正常,但该API已被废弃,尝试使用替代方案combineLatestWith时,无法使用pipe操作符,报错信息如下:
Property 'pipe' does not exist on type 'OperatorFunction<unknown, [unknown, string, number, boolean]>'
相关代码:
export class TestService implements OnDestroy { private _viewName$: BehaviorSubject<string> = new BehaviorSubject<string>(''); public depth$: BehaviorSubject<number> = new BehaviorSubject<number>(2); public graphMode$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); private _loadSubtree$(rootId: string, showGlobalLoadingIndicator: boolean = false): Observable<OprTreeGridItem<CI>[]> { //Below line has the error return combineLatestWith(this._viewName$, this.depth$, this.graphMode$).pipe( tap(() => this._isSubtreeLoading$.next(showGlobalLoadingIndicator)), switchMap(([viewName, depth, graphMode]) => this._topViewGraphHttpService.getTopViewGraph(viewName, depth, -1, rootId, null, graphMode).pipe( catchError(() => of([])) )), map((topViewGraphDto: TopViewGraphDTO) => topViewGraphDto.graph), withLatestFrom(this._viewName$, this._pickedCis$.pipe(startWith([])), this.includeViewAsRoot$), tap(([nodesAndRelationsDto, viewName, pickedCis, includeViewAsRoot]: [TopViewGraphNodesAndRelationsDTO, string, CI[], boolean]) => { console.log("something") }), map(() => { // some code }) ); } }
原因分析
combineLatestWith和废弃的combineLatest本质用法完全不同:
- 旧版多参数的
combineLatest是创建类函数,可以直接传入多个Observable并返回新的Observable,因此能直接链式调用pipe。 combineLatestWith是管道操作符,它必须依附于某个已存在的Observable,在其pipe方法内部使用,用来将当前流与传入的其他Observable合并。直接调用combineLatestWith(...)返回的是OperatorFunction类型(操作符本身),而非Observable,自然没有pipe方法。
解决方案
根据你的业务场景,推荐两种修正方式:
方式1:使用数组参数的combineLatest(新版RxJS兼容写法)
RxJS只是废弃了多参数的combineLatest,但保留了传入Observable数组的重载版本,这是官方推荐的替代方案,完全贴合你原本的逻辑:
return combineLatest([this._viewName$, this.depth$, this.graphMode$]).pipe( tap(() => this._isSubtreeLoading$.next(showGlobalLoadingIndicator)), switchMap(([viewName, depth, graphMode]) => this._topViewGraphHttpService.getTopViewGraph(viewName, depth, -1, rootId, null, graphMode).pipe( catchError(() => of([])) )), map((topViewGraphDto: TopViewGraphDTO) => topViewGraphDto.graph), withLatestFrom(this._viewName$, this._pickedCis$.pipe(startWith([])), this.includeViewAsRoot$), tap(([nodesAndRelationsDto, viewName, pickedCis, includeViewAsRoot]: [TopViewGraphNodesAndRelationsDTO, string, CI[], boolean]) => { console.log("something") }), map(() => { // some code }) );
方式2:正确使用combineLatestWith操作符
如果一定要用combineLatestWith,需要先定义一个源Observable(比如用of(undefined)作为初始触发流),然后在其pipe内部使用该操作符,注意解构时要忽略源流的冗余值:
return of(undefined).pipe( combineLatestWith(this._viewName$, this.depth$, this.graphMode$), tap(() => this._isSubtreeLoading$.next(showGlobalLoadingIndicator)), switchMap(([_, viewName, depth, graphMode]) => this._topViewGraphHttpService.getTopViewGraph(viewName, depth, -1, rootId, null, graphMode).pipe( catchError(() => of([])) )), map((topViewGraphDto: TopViewGraphDTO) => topViewGraphDto.graph), withLatestFrom(this._viewName$, this._pickedCis$.pipe(startWith([])), this.includeViewAsRoot$), tap(([nodesAndRelationsDto, viewName, pickedCis, includeViewAsRoot]: [TopViewGraphNodesAndRelationsDTO, string, CI[], boolean]) => { console.log("something") }), map(() => { // some code }) );
显然方式1更简洁,无需处理冗余值,是更适合你的选择。
内容的提问来源于stack exchange,提问作者Shubhangi Garg
相关产品推荐
相关产品推荐

