You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular HTTP拦截器报错:Type 'unknown'无法赋值给'HttpEvent<any>'

问题描述

在Angular应用中实现加载Spinner时,按照旧教程编写HTTP拦截器的intercept函数,第一个catchError管道正常,但第二个map管道出现类型错误,错误信息如下:

Argument of type 'OperatorFunction<HttpEvent<any>, any>' is not assignable to parameter of type 'OperatorFunction<unknown, any>'.
  Type 'unknown' is not assignable to type 'HttpEvent<any>'.ts(2345)

VSCode和Visual Studio中均出现该错误,推测是2020年后Angular Observable机制更新导致。相关拦截器代码如下:

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 {

    constructor(
        private _loading: LoadingService
    ) { }

    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;
            }));
      }
}
解决方法

问题出在catchError的返回值处理上——新版本RxJS要求catchError回调必须返回Observable类型,直接返回err会让后续流的类型被推断为unknown,和map期望的HttpEvent<any>类型不兼容,才触发了这个错误。

按以下步骤修改即可解决:

  • 先确保导入throwError工具函数:
import { Observable, throwError } from 'rxjs';
  • 修改catchError的返回逻辑,用throwError包装错误对象,保证流的类型一致性:
.pipe(catchError((err) => {
    this._loading.setLoading(false, request.url);
    return throwError(() => err); // 用throwError包装后返回Observable,不破坏原流类型
}))
  • (可选优化)把两个pipe调用合并成一个,让代码更简洁:
return next.handle(request)
    .pipe(
        catchError((err) => {
            this._loading.setLoading(false, request.url);
            return throwError(() => err);
        }),
        map((evt: HttpEvent<any>) => {
            if (evt instanceof HttpResponse) {
                this._loading.setLoading(false, request.url);
            }
            return evt;
        })
    );

修改完成后,类型错误会消失,因为catchError现在返回的是符合规范的Observable,后续map能正确识别输入类型为HttpEvent<any>。

内容的提问来源于stack exchange,提问作者nbofni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 09:10:54