-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Closed
Labels
QuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
Description
This could totally by my usage!!
The problem I'm trying to solve, is we have a TON of overloads for functions like forkJoin in RxJS. Which can be seen here.
Basically this pattern were you have to have N overloads for N arguments:
export function forkJoin<A>(sources: [ObservableInput<A>]): Observable<[A]>;
export function forkJoin<A, B>(sources: [ObservableInput<A>, ObservableInput<B>]): Observable<[A, B]>;
export function forkJoin<A, B, C>(sources: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>]): Observable<[A, B, C]>;What we really would like to be able to do is figure out a way to type this in just a few lines... and I was able to get very very close today, but it's still not quite right.
TypeScript Version: 4.1.0-dev.20201013
Search Terms:
Code
class Observable<T> {
observable!: T;
}
class ObservableInput<T> {
observableInput!: T
}
function forkJoin<O extends readonly ObservableInput<any>[]>(args: O): Observable<ObservableMapper<O>>;
function forkJoin<O extends readonly ObservableInput<any>[]>(...args: O): Observable<ObservableMapper<O>>;
function forkJoin(args: any): Observable<ObservableMapper<any>> {
return {} as any;
}
declare let os: [ ObservableInput<1>, ObservableInput<2>, ObservableInput<3>, ObservableInput<4> ];
declare let o1: ObservableInput<number>
declare let o2: ObservableInput<string>;
const os2 = [o1, o2] as const;
const foo = forkJoin(o1, o2); // $ExpectType Observable<[number, string]>
const bar = forkJoin([o1, o2] as const); // $ExpectType Observable<[number, string]>
const bar2 = forkJoin([o1, o2]); // $ExpectType Observable<[number, string]>
const baz = forkJoin(os); // $ExpectType Observable<[1, 2, 3, 4]>
const baz2 = forkJoin(os2); // $ExpectType Observable<[number, string]>
type ObservableMapper<T extends readonly any[]> =
T extends [] ? [] :
T extends readonly [ObservableInput<infer U>, ...infer Rest] ? [U, ...ObservableMapper<Rest>] :
T extends ObservableInput<infer U>[] ? U[] : never;Expected behavior:
forkJoin([o1, o2]) (aka bar2) would be of type Observable<[number, string]>.
Actual behavior:
forkJoin([o1, o2]) (aka bar2) is of type Observable<(number | string)[]>.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
QuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code