My mergeArrays
generic function is designed to not rely on the order of parameters. However, when it is used within another generic function, the result seems to depend on the order. This unexpected behavior is puzzling.
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>;
Here is an example of how this generic function is used:
type LargestArgumentsList<T extends ReadonlyArray<any>> = T extends readonly [
(...args: infer Args) => any,
...infer Rest
] ?
mergeArrays<LargestArgumentsList<Rest>, Args> // If I swap these parameters, the behavior changes even though mergeArrays should be order-independent
: readonly [];
This implementation works as expected. However, when I switch the parameters like this:
type LargestArgumentsList<T extends ReadonlyArray<any>> = T extends readonly [
(...args: infer Args) => any,
...infer Rest
] ?
mergeArrays<Args, LargestArgumentsList<Rest>>
: readonly [];
The behavior of LargestArgumentsList
differs from the previous scenario.
I have been trying to create a generic function that finds the longest list of arguments in an array of functions. While testing, I confirmed that my mergeArrays
does not rely on parameter order. However, within the context of another generic function (LargestArgumentsList
), this assumption does not hold true.