According to a comment by martin on Stack Overflow, the issue with typescript rxjs version 6.6.0 subscription lies in using the incorrect type for complete
. Instead of (value: unknown) => void
, it should be () => void
.
I would like to delve into why this error is displayed as it is.
The problematic method, subscribe
, in RxJS has multiple signature overloads as found in its codebase here.
subscribe(observer?: PartialObserver<T>): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: null | undefined, error: null | undefined, complete: () => void): Subscription;
/** @deprecated Use an observer instead of an error callback */
subscribe(next: null | undefined, error: (error: any) => void, complete?: () => void): Subscription;
/** @deprecated Use an observer instead of a complete callback */
subscribe(next: (value: T) => void, error: null | undefined, complete: () => void): Subscription;
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
When calling this method, TypeScript evaluates the overloads sequentially from top to bottom.
The object passed by OP was
{
next: (value) => {},
error: (value) => {},
complete: (value) => {},
}
Initially, the inferred signatures were
{
next: (value: unknown) => void,
error: (value: unknown) => void,
complete: (value: unknown) => void,
}
Type inference occurs only when the correct overload is determined based on argument compatibility in the subscribe
method.
As TypeScript matches the first signature, it expects a PartialObserver
object which must include at least one of next
, error
, or complete
properties. The provided object did not fit due to the wrong type for complete
.
This mismatch could lead to silent errors in some TypeScript versions, causing confusion. Subsequent mismatches in other signatures may also occur depending on the version used.
In a similar example run on TS version 4.2.3, the error message is more detailed, showing clearer information compared to what the OP encountered with TS2554:
No overload matches this call.
Overload 1 of 5, '(observer?: PartialObserver<unknown> | undefined): Subscription', gave the following error.
Type '(value: any) => void' is not assignable to type '() => void'.
Overload 2 of 5, '(next?: ((value: unknown) => void) | undefined, error?: ((error: any) => void) | undefined, complete?: (() => void) | undefined): Subscription', gave the following error.
Argument of type '{ next: (value: unknown) => void; error: (value: any) => void; complete: (value: any) => void; }' is not assignable to parameter of type '(value: unknown) => void'.
Object literal may only specify known properties, and 'next' does not exist in type '(value: unknown) => void'.
To avoid such confusing errors, it's important to understand and evaluate all possible overloads while troubleshooting.