Search code examples
reactjsfunctiontypescriptrxjsaccumulator

TypeScript/React how does scan operator work where currentvalue = function interface?


I have a scan operator with the following arguments:

.scan(function (acc:Message[], x: (msg: Message[]) => Message[]){ return x(acc); }, initialMessages)

my question is what return x(acc) returns actually? how does the accumulator function work in this particular case? I am quite new to TypeScript and lambda expressions, so any help is much appreciated.


Solution

  • In this case the type of x(acc) would be Message[]. You can tell this from the signature of the 2nd argument x, which returns Message[].

    Usually scan() accepts a function (acc, val) => ... with accumulator and value. and emits the returned value. In this case the emitted value val entering the scan operator is a closure. it's a bit unusual, but perfectly fine. An example which outputs

    [ 1, 2, 3 ]
    [ 3, 4, 5 ]
    [ 4, 5, 6 ]
    

    ...would be:

    import { Observable } from 'rxjs/Rx';
    
    type Message = number;
    
    function scanFn(acc: Message[], x: (msg: Message[]) => Message[]): Message[] {
      return x(acc);
    }
    
    function mapFn(val: Message): (msg: Message[]) => Message[] {
      return x => x.map((y, i) => val + i);
    }
    
    Observable.from([1, 3, 4])
      .map(mapFn)
      .scan(scanFn, [1, 2, 3])
      .subscribe(console.log);