import type { Expect, Equal, IsAny, IsUnknown } from "type-testing"; import { Solution } from "./solution"; // biome-ignore lint/suspicious/noExplicitAny: type AnyArray = any[]; type PartialApplicationHelper = >( ...args: A ) => A extends AnyArray ? A["length"] extends T["length"] ? R : PartialApplicationHelper, R> : never; type PartialApplication unknown> = PartialApplicationHelper, ReturnType>; type ToArray = R["length"] extends T ? R : ToArray; type Subtract = ToArray extends [ ...ToArray, ...infer Rest, ] ? Rest["length"] : never; type ShiftN = T extends [ infer _First, ...infer Rest extends AnyArray, ] ? N extends 0 ? T : ShiftN> : never; // Sample function with multiple arguments const f = (arg1: number, arg2: string, arg3: boolean, arg4: Date) => { return `${arg1}, ${arg2}, ${arg3}, ${arg4.toDateString()}`; }; const partial = ) => ReturnType>( fn: T, ) => { // TODO: a real implementation here return fn as unknown as PartialApplication; }; const z: PartialApplication = partial(f); // Example calls: all should not be errors const result1 = z(0, "a", true, new Date()); // Direct call const result2 = z(0)("a", true, new Date()); // Partially applied const result3 = z(0, "a", true)(new Date()); // Another partial const result4 = z()(0, "a", true)(new Date()); // Another partial const result5 = z(0, "a", true); // fn missing last arg type IsUnknownOrAny = IsUnknown extends true ? true : IsAny extends true ? true : false; type HasUnknownOrAny = T extends [ infer First, ...infer Rest, ] ? IsUnknownOrAny extends true ? true : HasUnknownOrAny : false; type t0 = Expect>, false>>; type t1_actual = [ typeof result1, typeof result2, typeof result3, typeof result4, typeof result5, ]; type t1_expected = [ string, string, string, string, PartialApplicationHelper<[x: Date], string>, ]; type t1 = Expect>;