{"version":3,"file":"partialLastBind.cjs","names":[],"sources":["../src/partialLastBind.ts"],"sourcesContent":["import type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport type { RemedaTypeError } from \"./internal/types/RemedaTypeError\";\nimport type { StrictFunction } from \"./internal/types/StrictFunction\";\nimport type { TupleSplits } from \"./internal/types/TupleSplits\";\n\ntype PartialLastBindError<\n  Message extends string,\n  Metadata = never,\n> = RemedaTypeError<\"partialLastBind\", Message, { metadata: Metadata }>;\n\ntype TupleSuffix<T extends IterableContainer> = TupleSplits<T>[\"right\"];\n\ntype RemoveSuffix<\n  T extends IterableContainer,\n  Suffix extends TupleSuffix<T>,\n> = Suffix extends readonly []\n  ? T\n  : T extends readonly [...infer TRest, infer TLast]\n    ? Suffix extends readonly [...infer SuffixRest, infer _SuffixLast]\n      ? // SuffixLast extends TLast.\n        RemoveSuffix<TRest, SuffixRest>\n      : // Suffix (as a whole) extends readonly TLast[].\n        // Suffix could possibly be empty, so this has to be TLast?.\n        [...RemoveSuffix<TRest, Suffix>, TLast?]\n    : // T has an optional or rest parameter last. If T is a parameter list,\n      // this can only happen if we have optional arguments or a rest param;\n      // both cases are similar.\n      T extends readonly [...infer TRest, (infer _TLast)?]\n      ? Suffix extends readonly [...infer SuffixRest, infer _SuffixLast]\n        ? // SuffixLast extends TLast.\n          RemoveSuffix<TRest, SuffixRest>\n        : // Suffix (as a whole) extends [...TRest, TLast?].\n          TRest\n      : // We got passed a parameter list that isn't what we expected; this\n        // is an internal error.\n        PartialLastBindError<\"Function parameter list has unexpected shape\", T>;\n\n/**\n * Creates a function that calls `func` with `partial` put after the arguments\n * it receives. Note that this doesn't support functions with both optional\n * and rest parameters.\n *\n * Can be thought of as \"freezing\" some portion of a function's arguments,\n * resulting in a new function with a simplified signature.\n *\n * Useful for converting a data-first function to a data-last one.\n *\n * @param func - The function to wrap.\n * @param partial - The arguments to put after.\n * @returns A partially bound function.\n * @signature\n *    partialLastBind(func, ...partial);\n * @example\n *    const fn = (x: number, y: number, z: number) => x * 100 + y * 10 + z;\n *    const partialFn = partialLastBind(fn, 2, 3);\n *    partialFn(1); //=> 123\n *\n *    const parseBinary = partialLastBind(parseInt, \"2\");\n *    parseBinary(\"101\"); //=> 5\n *\n *    pipe(\n *      { a: 1 },\n *      // instead of (arg) => JSON.stringify(arg, null, 2)\n *      partialLastBind(JSON.stringify, null, 2),\n *    ); //=> '{\\n  \"a\": 1\\n}'\n * @dataFirst\n * @category Function\n * @see partialBind\n */\nexport function partialLastBind<\n  F extends StrictFunction,\n  SuffixArgs extends TupleSuffix<Parameters<F>>,\n  RemovedSuffix extends RemoveSuffix<Parameters<F>, SuffixArgs>,\n>(\n  func: F,\n  ...partial: SuffixArgs\n): (\n  ...rest: RemovedSuffix extends IterableContainer ? RemovedSuffix : never\n) => ReturnType<F> {\n  // @ts-expect-error [ts2345, ts2322] -- TypeScript infers the generic sub-\n  // types too eagerly, making itself blind to the fact that the types match\n  // here.\n  return (...rest) => func(...rest, ...partial);\n}\n"],"mappings":"mEAqEA,SAAgB,EAKd,EACA,GAAG,EAGc,CAIjB,OAAQ,GAAG,IAAS,EAAK,GAAG,EAAM,GAAG,EAAQ"}