combineLatest 使用 6 个或更多流抛出 TS2349

Ita*_*nex 8 rxjs typescript angular

这是我第一次涉足 RxJS,所以如果有更好的解决方案,我完全赞成。我的目标是收集相关对象并在代码中加入它们(本质上是一个 sql 左连接)。这源于我使用 Angular In Memory API 对象作为数据库,直到它建立为止。

当我结合 Plans、Specieses、Codebooks、UpstreamModalities 和 TissueProcessions 时,此代码按预期工作。当我包含 Probes、Imaging 和 Analysises 流时,我对读取错误 blob 感到头疼。基本上 array.map 函数中的每一行都会抛出 TS2349 错误,即使是在添加其余三个源之前工作的那些。

import { Component, OnInit } from '@angular/core';
import { Plan } from '../plan';
import { PlanService } from '../plan.service';
import { DatabaseService } from 'src/app/serivces/database.service';
import { combineLatest } from 'rxjs';
import { map, tap } from 'rxjs/operators';

@Component({
  selector: 'app-plans-list',
  templateUrl: './plans-list.component.html',
  styleUrls: ['./plans-list.component.scss']
})
export class PlansListComponent implements OnInit {
  plans$ = combineLatest([
    this.planService.getPlans(),
    this.databaseService.getSpecieses(),
    this.databaseService.getCodebooks(),
    this.databaseService.getUpstreamModalities(),
    this.databaseService.getTissueProcessions(),
    this.databaseService.getProbes(),
    this.databaseService.getImagings(),
    this.databaseService.getAnalysises(),
  ])
    .pipe(
      tap(x => console.log(`Plans.join lookup tables: `, x)),
      map(
        // destructuring
        ([plans, 
          specieses, 
          codebooks, 
          modalities, 
          tissues,
          probes,
          imagings, 
          analysises
        ]) =>
          plans.map(plan =>
            ({
              ...plan,
              species: specieses.find(x => x.id === plan.speciesId).shortName,
              codebook: codebooks.find(x => x.id === plan.codebookId).codebookName,
              upstreamModality: modalities.find(x => x.id === plan.upstreamModalityId).SOPName,
              tissueProcession: tissues.find(x => x.id === plan.tissueProcessionId).SOPName,
              probe: probes.find(x => x.id === plan.probeId).SOPName,
              imaging: imagings.find(x => x.id === plan.imagingId).SOPName,
              analysis: analysises.find(x => x.id === plan.analysisId).SOPName,
            }) as Plan
          )
      )
    )


  constructor(
    private planService: PlanService,
    private databaseService: DatabaseService
  ) { }

  ngOnInit() {  }
}
Run Code Online (Sandbox Code Playgroud)

这个 TS 验证是否只是因为流的数量而窒息?由于代码仍然按预期编译和执行。

ERROR in src/app/plans/plans-list/plans-list.component.ts(40,11): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '(<U>(callbackfn: (value: Plan, index: number, array: Plan[]) => U, thisArg?: any) => U[]) | (<U>(callbackfn: (value: StandardOperatingProcess, index: number, array: StandardOperatingProcess[]) => U, thisArg?: any) => U[]) | (<U>(callbackfn: (value: Species, index: number, array: Species[]) => U, thisArg?: any) => U[...' has no compatible call signatures.
    src/app/plans/plans-list/plans-list.component.ts(43,24): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ <S extends Plan>(predicate: (this: void, value: Plan, index: number, obj: Plan[]) => value is S, thisArg?: any): S; (predicate: (value: Plan, index: number, obj: Plan[]) => boolean, thisArg?: any): Plan; } | { ...; } | { ...; } | { ...; }' has no compatible call signatures.
    src/app/plans/plans-list/plans-list.component.ts(44,25): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ <S extends Plan>(predicate: (this: void, value: Plan, index: number, obj: Plan[]) => value is S, thisArg?: any): S; (predicate: (value: Plan, index: number, obj: Plan[]) => boolean, thisArg?: any): Plan; } | { ...; } | { ...; } | { ...; }' has no compatible call signatures.
    src/app/plans/plans-list/plans-list.component.ts(45,33): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ <S extends Plan>(predicate: (this: void, value: Plan, index: number, obj: Plan[]) => value is S, thisArg?: any): S; (predicate: (value: Plan, index: number, obj: Plan[]) => boolean, thisArg?: any): Plan; } | { ...; } | { ...; } | { ...; }' has no compatible call signatures.
    src/app/plans/plans-list/plans-list.component.ts(46,33): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ <S extends Plan>(predicate: (this: void, value: Plan, index: number, obj: Plan[]) => value is S, thisArg?: any): S; (predicate: (value: Plan, index: number, obj: Plan[]) => boolean, thisArg?: any): Plan; } | { ...; } | { ...; } | { ...; }' has no compatible call signatures.
    src/app/plans/plans-list/plans-list.component.ts(47,22): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ <S extends Plan>(predicate: (this: void, value: Plan, index: number, obj: Plan[]) => value is S, thisArg?: any): S; (predicate: (value: Plan, index: number, obj: Plan[]) => boolean, thisArg?: any): Plan; } | { ...; } | { ...; } | { ...; }' has no compatible call signatures.
    src/app/plans/plans-list/plans-list.component.ts(48,24): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ <S extends Plan>(predicate: (this: void, value: Plan, index: number, obj: Plan[]) => value is S, thisArg?: any): S; (predicate: (value: Plan, index: number, obj: Plan[]) => boolean, thisArg?: any): Plan; } | { ...; } | { ...; } | { ...; }' has no compatible call signatures.
    src/app/plans/plans-list/plans-list.component.ts(49,25): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ <S extends Plan>(predicate: (this: void, value: Plan, index: number, obj: Plan[]) => value is S, thisArg?: any): S; (predicate: (value: Plan, index: number, obj: Plan[]) => boolean, thisArg?: any): Plan; } | { ...; } | { ...; } | { ...; }' has no compatible call signatures.
Run Code Online (Sandbox Code Playgroud)

mar*_*tin 6

这是真的,源 Observable 的最大数量为 6,请参阅https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/combineLatest.ts#L68

但是,唯一的原因是它不太可能有这么多输入,因此没有为此定义函数重载。这仍然不限制您组合多个combineLatests:

combineLatest([
  combineLatest([s1, s2, ...]),
  combineLatest([s7, s8, ...]),
]).pipe(
  map(([results1, results2]) => [...results1, ...results2]),
);
Run Code Online (Sandbox Code Playgroud)

顺便说一句,这是一个您应该能够抑制的 TypeScript 错误@ts-ignore(即使您以后可能会错过其他 TypeScript 错误):

// @ts-ignore
plans$ = combineLatest([
  this.planService.getPlans(),
  this.databaseService.getSpecieses(),
  ...
  this.databaseService.getAnalysises(),
])
Run Code Online (Sandbox Code Playgroud)