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

Angular Http拦截器catchError报TS2345/TS7030类型错误如何解决

Angular Http错误拦截器TS2345、TS7030类型错误修复

错误根因

两个类型报错本质是同一个问题导致的:

  • catchError操作符要求传入的错误回调必须在所有执行分支返回符合ObservableInput类型的结果
  • 你当前代码中处理401、403状态码的分支仅执行了弹窗提示、登出操作,没有返回任何值,该分支隐式返回undefined:
    • 直接触发TS7030:不是所有代码路径都返回值
    • 同时触发TS2345:undefined类型不满足ObservableInput<any>的类型约束,无法传给catchError作为回调返回值

修复方案

  1. 补全401/403状态码分支的返回逻辑,和其他错误分支保持一致,组装错误信息后通过throwError返回可观察错误对象
  2. 清理代码中冗余内容:移除未使用的finalize导入、末尾多余分号、不必要的类型强转,删除提前声明的无用error变量

修复后完整代码

import {Injectable} from "@angular/core";
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent,
HttpErrorResponse
} from "@angular/common/http";
import {Observable, throwError} from "rxjs";
import {catchError} from "rxjs/operators";
import {AuthService} from "./auth.service";
import {Router} from "@angular/router";
import {MatSnackBar} from "@angular/material/snack-bar";

@Injectable({
  providedIn: "root"
})
export class ErrorInterceptorService implements HttpInterceptor {
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      catchError((err: HttpErrorResponse) => {
        // 401/403 未授权/登录过期处理
        if ([401, 403].includes(err.status)) {
          this.openSnackBar('Login Session has expired!', 'OK');
          this.authService.userLogout();
          const error = err.message || err.statusText;
          return throwError(error);
        } 
        // 404 资源不存在处理
        else if (err.status === 404) {
          this.router.navigate(["/notFoundResource", err.status], {
            queryParams: {
              "Error-Status": err.status
            }
          });
          const error = err.message || err.statusText;
          return throwError(error);
        } 
        // 400/500 客户端/服务端错误处理
        else if (err.status === 500 || err.status === 400) {
          this.router.navigate(["/applicationError", err.status], {
            queryParams: {
              "Error-Status": err.status
            }
          });
          const error = err.message || err.statusText;
          return throwError(error);
        }
        // 其他未知错误兜底
        else{
          const error = err.message || err.statusText;
          return throwError(error)
        }
      })
    )
  }

  openSnackBar(message: string, action: string) {
    this.snackBar.open(message, action, {
      duration: 2000
    })
  }

  constructor(private authService: AuthService,
              private router: Router, private snackBar: MatSnackBar) {
  }
}

补充优化点:如果需要在登出后自动跳转登录页,可以在401/403分支的userLogout()调用后补充路由跳转逻辑,不会影响返回值的类型校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:06:17