Home > Net >  RxJS, Typescript and the dreaded 'Type Mismatch' warning/error
RxJS, Typescript and the dreaded 'Type Mismatch' warning/error

Time:09-08

I know I'm missing something obvious. Below is pseudo code that actually works in production. But, the IDE (IntelliJ IDEA) is giving me an error that I can't crack. It can be suppressed with noinspection TypeScriptValidateTypes, but, what I'd really like to know is what's going on:

this.authService.onAuthStateChanged()
    .pipe(
        withLatestFrom(
            this.activatedRoute.queryParams.pipe(
                map(params => params['returnUrl'])
            )
        )
    )
    .subscribe(([authState, returnUrl]) => {
        // [...]
    });

The error I get on the subscribe line:

Argument type ([authState, returnUrl]: readonly [any, any]) => void is not assignable to parameter type Partial<Observer<[(AuthState | undefined), ...unknown[]]>> | undefined

Other pertinent details?

// AuthState is just a POJO.
onAuthStateChanged(): BehaviorSubject<AuthState | undefined>

// This is Angular's params object.
// https://angular.io/api/router/Params
export declare type Params = {
    [key: string]: any;
};

I'm using RxJS ~7.5.0, and Typescript ~4.7.4. I'm also using Angular ^14.2.0, although this really isn't an Angular problem.

So, what is supposed to happen here? onAuthStateChanged emits AuthState or undefined depending on whether the user is logged in. This is combined with a query parameter called returnUrl, which is a string, of course.

Now, the way the syntax used to work is that the two observables would be available using a destructuring assignment signature ([authState, returnUrl]) -- at least I think that's what it's called. And as I said, it compiles and executes correctly in real life And as others have shown here, also does not error on StackBlitz (updated to more closely match my environment with identical tslint, angular.json etc.).

And yet, my beloved IntelliJ...

Could it be that I am looking at a breaking change in the latest version of RxJS:

withLatestFrom

  • Generic signatures have changed. Do not explicitly pass generics.

Source: https://rxjs.dev/6-to-7-change-summary#withlatestfrom

Which is grand, except that it still compiles and runs. So, two things:

  1. What is happening behind the scenes to cause this error in IntelliJ?
  2. How do I make it go away? I've tried strongly typing all the parameters, to no avail...

CodePudding user response:

If you define onAuthStateChanged as either a function that returns a BehaviourSubject or, directly, as a BehaviourSubject, you should not have any error.

The following code does not produce any type error

type AuthState = {};

let onAuthStateChanged = new BehaviorSubject<AuthState | undefined>(null);
let onAuthStateChangedFunc: () => BehaviorSubject<AuthState | undefined>;

// This is Angular's params object.
// https://angular.io/api/router/Params
type Params = {
  [key: string]: any;
};

class Foo {
  constructor(private activatedRoute: ActivatedRoute) {}

  foo() {
    onAuthStateChangedFunc() // or
    // onAuthStateChanged
      .pipe(
        withLatestFrom(
          this.activatedRoute.queryParams.pipe(
            map((params) => params['returnUrl'])
          )
        )
      )
      .subscribe(([authState, returnUrl]) => {
        // [...]
      });
  }
}

The variables [authState, returnUrl] are correctly identified of type AuthState and any respectively.

See this stackblitz for reference

CodePudding user response:

The issue is tracked at WEB-57220, please follow it for updates

Enabling the Typescript language service in Settings | Languages & Frameworks | TypeScript should help to get rid of the error

  • Related