I have generic mergeArrays
which does not depend on order of parameters.
But when used inside another generic it seems result depend. But it is not understandable.
type Fn = (...args: any[]) => any;
type arr1LessThanOrEqual<
T1 extends ReadonlyArray<any>,
T2 extends ReadonlyArray<any>
> = T1["length"] extends T2["length"]
? true
: T2["length"] extends 0
? false
: T2 extends [infer First, ...infer Rest]
? Rest extends ReadonlyArray<any>
? arr1LessThanOrEqual<T1, Rest>
: never
: never;
type mergeArrWithLeft<
T1 extends ReadonlyArray<any>,
T2 extends ReadonlyArray<any>
> = readonly [
...{
readonly [Index in keyof T1]: Index extends keyof T2
? (T1[Index] & T2[Index])
: T1[Index];
}
];
type mergeArrays<
T1 extends ReadonlyArray<any>,
T2 extends ReadonlyArray<any>
> = arr1LessThanOrEqual<T1, T2> extends true
? mergeArrWithLeft<T2, T1>
: mergeArrWithLeft<T1, T2>;
and here i use this generic:
type LargestArgumentsList<T extends ReadonlyArray<any>> = T extends readonly [
(...args: infer Args) => any,
...infer Rest
] ?
mergeArrays<LargestArgumentsList<Rest>, Args> // here if I swap it does not work, but generic mergeArrays does not depend on order of params, so it is a mistery
: readonly [];
and it works. but if i swap it to:
type LargestArgumentsList<T extends ReadonlyArray<any>> = T extends readonly [
(...args: infer Args) => any,
...infer Rest
] ?
mergeArrays<Args, LargestArgumentsList<Rest>>
: readonly [];
the behaviour of LargestArgumentsList
is different, here is playground
I tried to create a generic which finds the longest list of arguments in array of function.
And i expect mergeArrays
generic to not depend on order of parameters. I tested and it does not depend on order of parameters. But inside another generic(LargestArgumentsList
) it works differently.
CodePudding user response:
The definition of arr1LessThanOrEqual
is missing a readonly
in the T2 extends [infer First, ...infer Rest]
constraint. Since Args
is not readonly, arr1LessThanOrEqual
works when Args
is the second parameter, but if you swap it with the readonly LargestArgumentsList<Rest>
, it will fail.
If you replace the constraint with
T2 extends readonly [infer First, ...infer Rest]
LargestArgumentsList
will work even when the parameters are swapped.