mysomic
mysomic

Reputation: 1567

Why can't I reduce to a different type in RxJs 6?

The example below doesn't work as a straight conversion from the chained operator in version 5. It gives a Typescript compiler error.

from([1, 2]).pipe(
    reduce((acc, curr) => {
        return acc + ' ';
    }, '')
);

Argument of type 'MonoTypeOperatorFunction' is not assignable to parameter of type 'OperatorFunction'. Types of parameters 'source' and 'source' are incompatible. Type 'Observable' is not assignable to type 'Observable'. Type 'number' is not assignable to type 'string'. [2345]

Upvotes: 1

Views: 1150

Answers (3)

So here is a working version

from([1, 2])
  .pipe(
    reduce<number, string>(
      (acc, curr) => {
        return acc + ' ';
      }, '')
  ).subscribe(x => {
    console.log(x);
  });

Now a bit of explanation, the problem here is coming from this line (which is from the rxjs source) and defines the function signature(types)

export function reduce<T>(accumulator: (acc: T, value: T, index: number) => T, seed?: T): MonoTypeOperatorFunction<T>;

So in your case because you are not defying types explicitly, rxjs thinks that the acc and the value are from the same type (number in your case, because you are passing array of numbers)

By defying explicitly the types of the function arguments we are fixing this problem, because we are kind of helping rxjs/ts to use the appropriate function signature that is below (this way no erros will be thrown)

export function reduce<T, R>(accumulator: (acc: R, value: T, index: number) => R, seed?: R): OperatorFunction<T, R>;

Here is the reduce source

If we have to sum it up, the problem is that rxjs/ts needs some explicit help with the typings.

Upvotes: 1

josepdecid
josepdecid

Reputation: 1847

It looks like that you have two different kinds of Observable library that come from separate copies of RxJS (maybe from an older version). Take a look at the package.json, the package.lock.json or node_modules folder for duplicated packages by doing $ npm ls rxjs or simply remove this package and perform another fresh install. Let me know if it works!

Upvotes: 0

thedude
thedude

Reputation: 9812

Edit: was answered before OP described he had issues with TypeScript

You need to import RxJs and subscribe to the stream:

rxjs.from([1, 2]).pipe(
    rxjs.operators.reduce((acc, curr) => {
        return acc + ' ' + curr;
    }, '')
).subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>

Upvotes: 0

Related Questions