I have created an interface type as follows:
interface Input<TOutput> { }
And then extended that interface with the following:
interface ExampleInput extends Input<ExampleOutput> { }
interface ExampleOutput { }
Additionally, I have defined a "service" interface like this:
interface Service {
invoke<TInput extends Input<TOutput>, TOutput>(input: TInput): Observable<TOutput>
}
However, when attempting to call it with an instance of ExampleInput
, it fails:
function example(service: Service) {
service.invoke({} as ExampleInput).subscribe((output: ExampleOutput) => {
console.log(output);
});
}
error TS2769: No overload matches this call.
Overload 1 of 3, '(observer?: Partial<Observer<unknown>> | undefined): Subscription', gave the following error.
Type '(output: ExampleOutput) => void' has no properties in common with type 'Partial<Observer<unknown>>'.
Overload 2 of 3, '(next: (value: unknown) => void): Subscription', gave the following error.
Argument of type '(output: ExampleOutput) => void' is not assignable to parameter of type '(value: unknown) => void'.
Types of parameters 'output' and 'value' are incompatible.
Type 'unknown' is not assignable to type 'ExampleOutput'.
Overload 3 of 3, '(next?: ((value: unknown) => void) | null | undefined, error?: ((error: any) => void) | null | undefined, complete?: (() => void) | null | undefined): Subscription', gave the following error.
Argument of type '(output: ExampleOutput) => void' is not assignable to parameter of type '(value: unknown) => void'.
Types of parameters 'output' and 'value' are incompatible.
Type 'unknown' is not assignable to type 'ExampleOutput'.
185 service.invoke({} as ExampleInput).subscribe((output: ExampleOutput) => {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Why does the return type of the Observable
's subscribe
callback show as either unknown
or void
, when I am expecting it to be ExampleOutput
?
To illustrate using a different language example, in JVM Kotlin, the code below compiles and behaves as expected after implementing appropriate functionality:
fun interface Subscriber<TOutput>
{
fun subscribe(callback: (output: TOutput) -> Unit): Unit
}
interface Input<TOutput>
interface ExampleInput : Input<ExampleOutput>
interface ExampleOutput
interface Service
{
fun <TInput : Input<TOutput>, TOutput> invoke(input: TInput): Subscriber<TOutput>
}
fun example(service: Service)
{
service.invoke(object : ExampleInput { }).subscribe { output: ExampleOutput ->
println(output)
}
}