Search code examples
typescriptrxjs

Typescript: RXJS `distinctUntilChanged` not working with strict / first parameter undefined


The following code doesn't work:

let observable: Observable<{ key: number }> = of({ key: 123 });
observable.pipe(
    distinctUntilChanged(undefined, v => v.key)
);

Although there is an overload:

export function distinctUntilChanged<T, K>(
  comparator?: (previous: K, current: K) => boolean,
  keySelector: (value: T) => K = identity as (value: T) => K
): MonoTypeOperatorFunction<T>

What's the reason for it?


Solution

  • The example provided, is not a TypeScript example, so undefined is not allowed in the below types as a first argument! instead just specify a default comparator and set the keySelector!

    Type Definition:

    import { MonoTypeOperatorFunction } from '../types';
    export declare function distinctUntilChanged<T>(comparator?: (previous: T, current: T) => boolean): MonoTypeOperatorFunction<T>;
    export declare function distinctUntilChanged<T, K>(comparator: (previous: K, current: K) => boolean, keySelector: (value: T) => K): MonoTypeOperatorFunction<T>;
    

    Code:

    import { of, distinctUntilChanged, Observable } from 'rxjs';
    export interface TypeObj {
      updatedBy: string;
      data: Array<string>;
    }
    // A stream of updates to a given account
    const accountUpdates$: Observable<TypeObj> = of(
      { updatedBy: 'blesh', data: [] },
      { updatedBy: 'blesh', data: [] },
      { updatedBy: 'ncjamieson', data: [] },
      { updatedBy: 'ncjamieson', data: [] },
      { updatedBy: 'blesh', data: [] }
    );
    
    // We only want the events where it changed hands
    const changedHands$ = accountUpdates$.pipe(
      distinctUntilChanged<TypeObj, string>(
        (prev: string, curr: string): boolean => prev === curr,
        (update: TypeObj) => update?.updatedBy
      )
    );
    
    changedHands$.subscribe(console.log);
    

    Stackblitz Demo