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:
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();
CodePudding user response:
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