Angular Http拦截器catchError报TS2345/TS7030类型错误如何解决
Angular Http错误拦截器TS2345、TS7030类型错误修复
错误根因
两个类型报错本质是同一个问题导致的:
catchError操作符要求传入的错误回调必须在所有执行分支返回符合ObservableInput类型的结果- 你当前代码中处理401、403状态码的分支仅执行了弹窗提示、登出操作,没有返回任何值,该分支隐式返回
undefined:- 直接触发TS7030:不是所有代码路径都返回值
- 同时触发TS2345:
undefined类型不满足ObservableInput<any>的类型约束,无法传给catchError作为回调返回值
修复方案
- 补全401/403状态码分支的返回逻辑,和其他错误分支保持一致,组装错误信息后通过
throwError返回可观察错误对象 - 清理代码中冗余内容:移除未使用的
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
相关产品推荐
相关产品推荐

