升级Angular12/RxJS7/TS4后void无法赋值为Subscription如何修复
错误原因
这个TS编译错误是升级RxJS 7.x带来的破坏性变更导致的:
- RxJS 6.x版本中,
Subscription.add()方法返回当前Subscription实例本身,支持链式调用赋值 - RxJS 7.x版本调整了API类型定义,
Subscription.add()的返回值改为void
你的代码中,是把.subscribe(...).add(...)整个链式调用的结果赋值给声明为Subscription类型的onBlurTimerSubscription属性,在RxJS7下这个链式调用的最终返回值是void,自然触发「Type 'void' is not assignable to type 'Subscription'」的类型错误。
你注释里提到的将属性类型改为Subscription | any的方案绝对不推荐,本质是主动绕过TypeScript的类型检查,会掩盖真实的API逻辑变化,给后续代码埋下隐性bug。
修复方案
不需要改动核心业务逻辑,只要拆分链式调用,不要把.add()的返回值用于赋值即可,调整后的代码如下:
const ALLOW_PRIORITY_OPTION_SELECTED_DELAY = 10 + this.debounceCustomEventDelay; // 先持有subscribe返回的订阅实例,完成类型匹配的赋值 this.onBlurTimerSubscription = timer(ALLOW_PRIORITY_OPTION_SELECTED_DELAY).subscribe(() => { this.onBlurComplete(event); }); // 单独添加订阅销毁时的清理逻辑,不需要接收add方法的返回值 this.onBlurTimerSubscription.add(() => { safeUnsubscribe(this.onBlurTimerSubscription); });
额外优化建议
你当前在add回调中手动调用safeUnsubscribe的逻辑存在冗余:RxJS的Subscription在流自然终止(timer延时到点、逻辑执行完成后会自动完结)、或者被手动调用unsubscribe时,会自动执行所有通过add绑定的清理逻辑,不需要在清理回调里再重复取消订阅自身。你只需要确保在组件销毁、下一次onBlur事件触发前,主动调用已存在的onBlurTimerSubscription的unsubscribe方法即可,避免重复创建订阅导致的逻辑重复执行问题。
内容的提问来源于stack exchange,提问作者js-newb
相关产品推荐
相关产品推荐

