[combineLatest] loses the tuple shape of array-literal sources, unlike [forkJoin]
Author: MaXalCreated Sep 16, 2026Updated Sep 16, 2026
Describe the bug
For a: Observable<number> and b: Observable<string>, Observable[combineLatest]([a, b]) returns Observable<(string | number)[]>. Destructured values cannot be assigned to number and string variables.
Observable[forkJoin]([a, b]) returns Observable<[number, string]> and the same assignments compile.
Expected behavior
Save the following as repro.ts in an empty directory, then run:
npm install [email protected] [email protected]
npx tsc --strict --lib esnext,dom --moduleResolution bundler --module preserve --declaration repro.tsimport "rxjs"
import { combineLatest } from "rxjs/combine-latest"
import { forkJoin } from "rxjs/fork-join"
declare const a: Observable<number>
declare const b: Observable<string>
export const cl = Observable[combineLatest]([a, b])
export const fj = Observable[forkJoin]([a, b])
cl.subscribe(([n, s]) => { const x: number = n; const y: string = s }) // errors
fj.subscribe(([n, s]) => { const x: number = n; const y: string = s }) // okRelevant declaration output and diagnostics:
export declare const cl: Observable<(string | number)[]>;
export declare const fj: Observable<[number, string]>;
repro.ts(11,34): error TS2322: Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
repro.ts(11,55): error TS2322: Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.Expected: the result preserves each position's type (number, then string), and both subscriptions compile.
Reproduction code
Reproduction URL
No response
Version
rxjs 9.0.0-beta.0
Environment
TypeScript 6.0.3 with strict. Same result with vue-tsc 3.3.11.
Additional context
Observable[combineLatest]([a, b] as const) returns Observable<readonly [number, string]> and the assignments compile.
Source: ReactiveX/rxjs