UNPKG

remeda

Version:

A utility library for JavaScript and Typescript.

1 lines 3.26 kB
{"version":3,"file":"partialBind.cjs","names":[],"sources":["../src/partialBind.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 PartialBindError<\n Message extends string,\n Metadata = never,\n> = RemedaTypeError<\"partialBind\", Message, { metadata: Metadata }>;\n\ntype TuplePrefix<T extends IterableContainer> = TupleSplits<T>[\"left\"];\n\ntype RemovePrefix<\n T extends IterableContainer,\n Prefix extends TuplePrefix<T>,\n> = Prefix extends readonly []\n ? T\n : T extends readonly [infer THead, ...infer TRest]\n ? Prefix extends readonly [infer _PrefixHead, ...infer PrefixRest]\n ? // PrefixHead extends THead.\n RemovePrefix<TRest, PrefixRest>\n : // Prefix (as a whole) extends ReadonlyArray<THead>.\n // Prefix could possibly be empty, so this has to be THead?.\n [THead?, ...RemovePrefix<TRest, Prefix>]\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 _THead)?, ...infer TRest]\n ? Prefix extends readonly [infer _PrefixHead, ...infer PrefixRest]\n ? // PrefixHead extends THead.\n RemovePrefix<TRest, PrefixRest>\n : // Prefix (as a whole) extends [THead?, ...TRest].\n TRest\n : // We got passed a parameter list that isn't what we expected; this is\n // an internal error.\n PartialBindError<\"Function parameter list has unexpected shape\", T>;\n\n/**\n * Creates a function that calls `func` with `partial` put before the arguments\n * it receives.\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 * @param func - The function to wrap.\n * @param partial - The arguments to put before.\n * @returns A partially bound function.\n * @signature\n * R.partialBind(func, ...partial);\n * @example\n * const fn = (x: number, y: number, z: number) => x * 100 + y * 10 + z;\n * const partialFn = R.partialBind(fn, 1, 2);\n * partialFn(3); //=> 123\n *\n * const logWithPrefix = R.partialBind(console.log, \"[prefix]\");\n * logWithPrefix(\"hello\"); //=> \"[prefix] hello\"\n * @dataFirst\n * @category Function\n * @see partialLastBind\n */\nexport function partialBind<\n F extends StrictFunction,\n PrefixArgs extends TuplePrefix<Parameters<F>>,\n RemovedPrefix extends RemovePrefix<Parameters<F>, PrefixArgs>,\n>(\n func: F,\n ...partial: PrefixArgs\n): (\n ...rest: RemovedPrefix extends IterableContainer ? RemovedPrefix : 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(...partial, ...rest);\n}\n"],"mappings":"AA4DA,SAAgB,EAKd,EACA,GAAG,EAGc,CAIjB,OAAQ,GAAG,IAAS,EAAK,GAAG,EAAS,GAAG,EAAK"}