网站搜索

javascript - 类型 'unknown' 不能分配给类型 'HttpEvent' - 尝试在 Angular 应用中创建 HTTP 拦截器


我一直在尝试在我的 Angular 应用程序中创建一个加载旋转器。

我在这里找到了一篇有趣的教程 (https://medium.com/swlh/angular-loading-spinner-using-http-interceptor-63c1bb76517b)。

一切进行得都很顺利,直到最后一步,我需要真正创建拦截函数的时候。

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor, HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators'
import { LoadingService } from './loading.service';

/**
 * This class is for intercepting http requests. When a request starts, we set the loadingSub property
 * in the LoadingService to true. Once the request completes and we have a response, set the loadingSub
 * property to false. If an error occurs while servicing the request, set the loadingSub property to false.
 * @class {HttpRequestInterceptor}
 */
@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {

    /**
     * 
     * @param _loading 
     */
    constructor(
        private _loading: LoadingService
    ) { }

    /**
    * Called at the start of every HTTP request. This function will try to activate the loading spinner
    * @param request 
    * @param next 
    * @returns 
    */
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this._loading.setLoading(true, request.url);
        return next.handle(request)
            .pipe(catchError((err) => {
                this._loading.setLoading(false, request.url);
                return err;
            }))
            .pipe(map<HttpEvent<any>, any>((evt: HttpEvent<any>) => {
                if (evt instanceof HttpResponse) {
                    this._loading.setLoading(false, request.url);
                }
                return evt;
            }));
      }
}

第一个管子没问题。

然而,第二根管道上有一条大红色下划线。错误提示如下:

类型为 'OperatorFunction<HttpEvent, any>' 的参数不可分配给类型为 'OperatorFunction<unknown, any>' 的参数。类型 'unknown' 不能分配给类型 'HttpEvent'.ts(2345)

我在 VSCode(蓝色的)和 Microsoft VS(紫色的)中都看到了错误,这意味着绝对是我的代码有问题,而不是我的 IDE 出现了奇怪的情况……

这篇文章写于2020年6月(4年前),所以Angular观察者的工作方式可能已经发生了变化?

我学习 Angular 大约一周了,也不是很熟悉 TypeScript,所以如果我缺少一些基础知识,请多包涵,但我会非常感激一些指导,因为我不确定下一步该如何进行……

如果 Stack Overflow 的专家们有任何建议,我们将非常感激。

谢谢!

答案#1

catchError 必须返回一个可观察对象,所以我使用 of 将错误转换为可观察对象,这在 map 下游引起了错误。

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    this._loading.setLoading(true, request.url);
    return next.handle(request).pipe(
      catchError((err) => {
        this._loading.setLoading(false, request.url);
        return of(err);
      }),
      map<HttpEvent<any>, HttpEvent<any>>((evt: HttpEvent<any>) => {
        if (evt instanceof HttpResponse) {
          this._loading.setLoading(false, request.url);
        }
        return evt;
      })
    );
  }