Repository navigation
Unable to infer types from callback in bindCallback function for RxJS #22952
Copy link
Copy link
Closed
Labels
Needs More InfoThe issue still hasn't been fully clarifiedThe issue still hasn't been fully clarified
Description
Currently type inference is unable to provide useful type inference for functions such as RxJS's bindCallback.
I have a PR here (ReactiveX/rxjs#3480) that tries to add overloads to support the desired behavior, but when I test it, it does not infer types properly.
TypeScript Version: latest as of this moment
Search Terms: callback type inference, wrapping node callbacks, variadic arguments
Code
export function bindCallback(callbackFunc: (callback: () => any) => any, scheduler?: SchedulerLike): () => Observable<void>;
export function bindCallback<R1>(callbackFunc: (callback: (res1: R1) => any) => any, scheduler?: SchedulerLike): () => Observable<R1>;
export function bindCallback<R1, R2>(callbackFunc: (callback: (res1: R1, res2: R2) => any) => any, scheduler?: SchedulerLike): () => Observable<[R1, R2]>;
export function bindCallback<R1, R2, R3>(callbackFunc: (callback: (res1: R1, res2: R2, res3: R3) => any) => any, scheduler?: SchedulerLike): () => Observable<[R1, R2, R3]>;
export function bindCallback<A1>(callbackFunc: (arg1: A1, callback: () => any) => any, scheduler?: SchedulerLike): (arg1: A1) => Observable<void>;
export function bindCallback<A1, R1>(callbackFunc: (arg1: A1, callback: (res1: R1) => any) => any, scheduler?: SchedulerLike): (arg1: A1) => Observable<R1>;
export function bindCallback<A1, R1, R2>(callbackFunc: (arg1: A1, callback: (res1: R1, res2: R2) => any) => any, scheduler?: SchedulerLike): (arg1: A1) => Observable<[R1, R2]>;
export function bindCallback<A1, R1, R2, R3>(callbackFunc: (arg1: A1, callback: (res1: R1, res2: R2, res3: R3) => any) => any, scheduler?: SchedulerLike): (arg1: A1) => Observable<[R1, R2, R3]>;
export function bindCallback<A1, A2>(callbackFunc: (arg1: A1, arg2: A2, callback: () => any) => any, scheduler?: SchedulerLike): (arg1: A1, arg2: A2) => Observable<void>;
export function bindCallback<A1, A2, R1>(callbackFunc: (arg1: A1, arg2: A2, callback: (res1: R1) => any) => any, scheduler?: SchedulerLike): (arg1: A1, arg2: A2) => Observable<R1>;
export function bindCallback<A1, A2, R1, R2>(callbackFunc: (arg1: A1, arg2: A2, callback: (res1: R1, res2: R2) => any) => any, scheduler?: SchedulerLike): (arg1: A1, arg2: A2) => Observable<[R1, R2]>;
function foo(a: number, b: number, callback: (c: string, d: string) => any): any {
setTimeout(() => callback(a + '!', b + '!');
}
const source = bindCallback(foo)(1, 3);Expected behavior:
source should be Observable<[string, string]>
Actual behavior:
source is Observable<void>
Related Issues:
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Needs More InfoThe issue still hasn't been fully clarifiedThe issue still hasn't been fully clarified
Activity
mhegazy commentedon Mar 28, 2018
From a cursory look, seems like you just ordered your overloads in the opposite order. i am guessing you want
export function bindCallback<A1, A2, R1, R2> ...to be at the top, sincebindCallback<A1, A2>(callbackFunc: ...that you have more generic and overload resolution proceeds in order of declarations.benlesh commentedon Mar 29, 2018
Thank you, Mohamed Hegazy (@mhegazy), that worked, however it's REALLY ugly. Haha. Ideally, there would be some way to have "spread generics" or the like.
Here's what the type overloads for RxJS's bindCallback looks like now:
It doesn't support every use case, it just seemed silly to go beyond a certain point.
benlesh commentedon Mar 29, 2018
In particular, notice above the lines that have an
R4, just so it can ignore that type and returnObservable<any[]>mhegazy commentedon Mar 29, 2018
Yeah, you need variadic types. We have been talking about it a lot lately, and i think we will start tackling it soon.
typescript-bot commentedon Apr 13, 2018
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.