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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:07:45