【问题标题】:TypeScript Types Error when using functions with tap and map RxJS operators?使用带有 tap 和 map RxJS 运算符的函数时出现 TypeScript 类型错误?
【发布时间】:2018-10-29 07:14:39
【问题描述】:

我遇到了奇怪的 TypeScript 错误,而且我很难理解问题所在。我的代码运行良好,但 PHPStorm IDE 抛出以下错误:

TS2345 Argument of Type 'UnaryFunction<Observable<{}>, Observable<{}>>' is not assignable to parameter of type 'OperatorFunction<Object, {}>'.

该错误出现在下面代码的点击功能上。

// Get Search Results
getSearchResults(payload: object): Observable<SearchResult[]> {
    let sbRef = this.snackBar.openFromComponent(SmallSpinnerComponent);
    let preparedPayload = this.addPayloadIdentifiers(payload);

    return this.http.post(environment.searchUrl, preparedPayload, {responseType: 'json'}).pipe(
        tap(res => console.log(res)),
        map(res => {
            sbRef.dismiss();
            return this.translateJSONResultSetV1(res);
        }),
        catchError(this.errorHandler.handleError(`getSearchResults error`))
);
}

如果我完全注释掉 tap 运算符,我会在 ma​​p 运算符上收到以下错误:

TS2345 Argument of Type 'UnaryFunction<Observable<{}>,
Observable<SearchResult[]>>' is not assignable to parameter of type
'OperatorFunction<Object, {}>'.
Types of parameters 'source' and 'source' are incompatible.
Type 'Observable<Object>' is not assignable to type 'Observable<{}>'

我很想这个错误真的很简单,但我似乎无法弄清楚是什么原因造成的。此外,从 RESTful 接收的 JSON 有效负载需要在客户端进行大量处理。这是不可避免的,所以我在 ma​​p 运算符中使用了一个辅助函数 translateJSONResultSetV1 来返回正确的对象类型。在 ma​​p 运算符中使用函数是否不正确?这会导致错误吗?

我想强调代码运行良好。但是,如果我不正确地使用 Observables,我想修复它,这样这段代码就不会因未来的更新而中断。

编辑: RxJS 版本 5.5.2

进口:

import { Injectable } from '@angular/core';
import { HttpClient} from '@angular/common/http';
import { environment } from "../../../environments/environment";
import { catchError, map, tap} from "rxjs/operators";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/merge';
import { ErrorHandlerService } from "./error-handler.service";
import { SearchFilterDropdown } from "../../classes/search-filter-dropdown";
import { SessionService } from "./session.service";
import { BusinessRule } from "../../classes/business-rule";
import { SearchResult } from "../../classes/search-result";
import { SectionHeading } from "../../classes/section-heading";
import { SmallSpinnerComponent } from "../../shared/small-spinner/small-spinner.component";
import { MatSnackBar } from "@angular/material";

【问题讨论】:

  • 你的导入是什么样的?顺便说一句,地图运算符中的 sbRef.dismiss 调用在语义上是错误的。这是一个副作用,所以它应该在一个点击操作符里面。
  • 另外,你用的是什么版本的rxjs?
  • 感谢您的回复!我添加了 RxJS 版本(5.5.2)和导入。实际上,我最初在点击操作符中有dismiss(),但在尝试调试时移动了它。我会把它放回去,但这并不能解决问题。我仍然遇到同样的错误。
  • 我会试试tap&lt;Object&gt;(res =&gt; console.log(res))
  • 你解决过这个问题吗?

标签: javascript angular typescript rxjs


【解决方案1】:

我的钱是您使用catchError 运算符。语句this.errorHandler.handleError('getSearchResults error') 需要返回一个返回可观察对象的方法。

catchError 就像一个 switchMap,当源 observable 发生错误时,可以推断出不同的类型。这个 edge case 运算符能够产生“非常简单,但我似乎无法弄清楚是什么原因造成的”的错误。

【讨论】:

    猜你喜欢
    • 2017-12-26
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 2021-05-10
    • 2016-06-21
    • 2021-10-14
    • 1970-01-01
    • 2021-01-10
    相关资源
    最近更新 更多