RxJS6中TypeError: .finalize is not a function问题的技术咨询
RxJS TypeError: finalize is not a function 问题解答
你遇到的错误是:
TypeError: this.authService.authServiceSigninUser(...).map(...).catch(...).finalize is not a function
相关代码:
public signinUser(user:UserSigninInfo):any{ this.loaderService.show(); //this shows a spinner return this.authService.authServiceSigninUser(user) .map(response=>{ console.log('response from backend service',response); let result= <HttpResponse<any>>response; let authToken = result.headers.get("x-auth-token") if(authToken == null) { console.log("no authToken") } else { console.log("authToken is ",authToken) localStorage.setItem('id_token', authToken); } return result; }) .catch(this.handleError) .finally(()=> this.loaderService.hide()) //hide the spinner }
问题1:为何TypeScript未在编译阶段捕获该错误?如何实现编译时捕获?
这个问题核心和RxJS版本差异以及操作符使用规范有关:
- 版本不匹配导致类型检查失效:RxJS 5.x里
finally是Observable原型上的方法,但RxJS 6+之后,所有操作符改为pipeable形式,还把finally改名为finalize,且不再挂载到Observable原型上。如果你的项目用RxJS 6+却还在用旧的链式调用写法,再加上类型定义(RxJS 6+自带类型,无需单独装@types/rxjs)没正确关联,TypeScript就没法在编译时检测到错误。 - 严格模式未开启:如果tsconfig.json里没开
strict: true,TypeScript的类型检查会比较宽松,这类不兼容的调用容易被漏掉。
要实现编译时捕获,你可以这么做:
- 统一遵循RxJS 6+的pipeable操作符规范:所有操作符都通过
pipe()调用,且显式导入需要的操作符,让TypeScript能通过类型定义严格校验。 - 确保RxJS版本统一,不要混合不同大版本的依赖。
- 在tsconfig.json中开启
strict: true,增强类型检查的严格性,提前发现这类问题。
问题2:如何解决该错误?
你试了finally和finalize都无效,本质是还在用RxJS 5的旧写法,RxJS 6+已经不支持直接在Observable上链式调用操作符了。正确的解决步骤如下:
1. 导入所需的pipeable操作符
在你的组件/service文件顶部,导入需要的操作符:
import { map, catchError, finalize } from 'rxjs/operators';
注意:RxJS 6+里原有的catch已经改名为catchError,不要再用旧的catch方法。
2. 修改代码为pipe链式调用
把原来的链式操作,全部放到pipe()方法中:
public signinUser(user: UserSigninInfo): Observable<HttpResponse<any>> { this.loaderService.show(); //this shows a spinner return this.authService.authServiceSigninUser(user) .pipe( map(response => { console.log('response from backend service', response); const result = <HttpResponse<any>>response; const authToken = result.headers.get("x-auth-token"); if (authToken == null) { console.log("no authToken"); } else { console.log("authToken is ", authToken); localStorage.setItem('id_token', authToken); } return result; }), catchError(this.handleError.bind(this)), // 绑定this,避免handleError里的this指向错误 finalize(() => this.loaderService.hide()) // 使用RxJS 6+的finalize操作符 ); }
额外提醒:
- 如果你的
handleError方法里用到了this,一定要用.bind(this)或者把handleError改成箭头函数,否则调用时this会指向undefined。 - 不要用
any作为返回值类型,改成明确的Observable<HttpResponse<any>>,让TypeScript能更好地帮你做类型校验。
内容的提问来源于stack exchange,提问作者Manu Chadha
相关产品推荐
相关产品推荐

