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.
>Solution :
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.