RxJS自定义multiply运算符遇TS2345编译错误,求修复方案
RxJS自定义运算符multiply的TS2345错误修复
问题场景
实现基于高阶函数的RxJS自定义运算符multiply时,编译触发TS2345类型错误,相关代码、错误信息及环境版本如下:
完整代码
import { Component } from '@angular/core'; import { Observable, of } from 'rxjs'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'benlesh'; test() { console.log('test'); const multiply = (multiplier: number) => (source: Observable<number>) => new Observable((subscriber) => { const subscription = source.subscribe({ next: (value) => subscriber.next(multiplier * value), error: (err) => subscriber.error(err), complete: () => subscriber.complete(), }); return () => { subscription.unsubscribe(); }; }); of(1, 2, 3, 4).pipe(multiply(2)).subscribe(console.log); const double = multiply(2); const doubled = of(1, 2, 3, 4).pipe(double); const doubledAgain = doubled.pipe(double); // 此处触发错误 doubledAgain.subscribe(console.log); } constructor() { this.test(); } }
错误信息
Error: src/app/app.component.ts:45:39 - error TS2345: Argument of type '(source: Observable<number>) => Observable<unknown>' is not assignable to parameter of type 'OperatorFunction<unknown, unknown>'. Types of parameters 'source' and 'source' are incompatible. Type 'Observable<unknown>' is not assignable to type 'Observable<number>'. Type 'unknown' is not assignable to type 'number'. 45 const doubledAgain = doubled.pipe(double);
环境版本
- rxjs: ~7.8.0
- typescript: ~5.0.2
- angular/compiler: ^16.0.0
错误原因
TypeScript无法自动推断new Observable的输出类型,导致运算符返回的Observable被识别为Observable<unknown>。当第二次调用pipe(double)时,doubled的类型被推断为Observable<unknown>,与double运算符要求的输入Observable<number>类型不匹配,触发类型错误。
修复方案
有两种规范的修复方式:
方式1:显式指定Observable泛型类型
在创建Observable时明确指定输出类型为number:
const multiply = (multiplier: number) => (source: Observable<number>) => // 显式指定泛型<number> new Observable<number>((subscriber) => { const subscription = source.subscribe({ next: (value) => subscriber.next(multiplier * value), error: (err) => subscriber.error(err), complete: () => subscriber.complete(), }); return () => { subscription.unsubscribe(); }; });
方式2:使用RxJS的OperatorFunction约束类型
导入OperatorFunction并使用它来约束高阶函数的返回类型,让类型推断更准确:
// 导入OperatorFunction import { Observable, of, OperatorFunction } from 'rxjs'; const multiply = (multiplier: number): OperatorFunction<number, number> => (source: Observable<number>) => new Observable((subscriber) => { const subscription = source.subscribe({ next: (value) => subscriber.next(multiplier * value), error: (err) => subscriber.error(err), complete: () => subscriber.complete(), }); return () => { subscription.unsubscribe(); }; });
两种方式都能让TypeScript正确识别运算符的输入输出类型,解决TS2345错误。
内容的提问来源于stack exchange,提问作者albertkao9
相关产品推荐
相关产品推荐

