Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

TypeCasting in RxJS Operators

I’m trying to perform typecasting in the following scenario:

of(1, 2, 3, "not a number")
  .pipe(
    filter((val) => typeof val === "number"),
    map((number) => number * 2)
  )
  .subscribe();

Inside the map operator the number parameter is of type number, because the array values were filtered. However, typescript is not able to pick this up by itself and it says that the type of number inside the map is string|number.
I tried to do typecasting in the following ways, but none of them is working.

Attempt 1:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

of(1, 2, 3, "string")
  .pipe(
    filter((val) => typeof val === "number") as number,
    map((number) => number * 2)
  )
  .subscribe();

Error -> Argument of type ‘number’ is not assignable to parameter of type ‘OperatorFunction<string | number, unknown>’.ts(2345)

Attempt 2:

of(1, 2, 3, "string")
  .pipe(
    filter((val) => typeof val === "number") as OperatorFunction<number,any>,
    map((number) => number * 2)
  )
  .subscribe();

Error -> Argument of type ‘OperatorFunction<number, any>’ is not assignable to parameter of type ‘OperatorFunction<string | number, any>’.
Type ‘string | number’ is not assignable to type ‘number’.
Type ‘string’ is not assignable to type ‘number’.ts(2345)

Attempt 3:(set the return type in the pipe)

of(1, 2, 3, "string")
  .pipe<number, number>(
    filter((val) => typeof val === "number"),
    map((number) => number * 2)
  )
  .subscribe();

Error -> Argument of type ‘MonoTypeOperatorFunction<string | number>’ is not assignable to parameter of type ‘OperatorFunction<string | number, number>’.
Type ‘Observable<string | number>’ is not assignable to type ‘Observable’.
Type ‘string | number’ is not assignable to type ‘number’.
Type ‘string’ is not assignable to type ‘number’.ts(2345)

(Valid, but too hacky) Attempt 4:
This attempt is the only one that works, but it looks too hacky, as inside the map operator I can set any type to the parameter number since the return type of fitler was marked as any .

of(1, 2, 3, "string")
  .pipe(
    filter((val) => typeof val === "number") as any,
    map((number: number) => number * 2)
  )
  .subscribe();

>Solution :

You need to add typeguard predicate val is number to the filter callback to narrow the type

of(1, 2, 3, "string")
  .pipe(
    filter((val): val is number => typeof val === "number"),
    map((number) => number * 2)
  )
  .subscribe();

More about type guards in the typescript docs

github issue

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading