Skip to content
VersionSize

fp

The fp utility enables "Functional Programming" mode for compatible toolkit functions. It converts a standard utility (where the array is usually the first argument) into a partially applied function where the data argument is moved to the end.

Source Code

View Source Code
ts
import type { Fn } from '../types';

type RemoveFirstParameter<T extends Fn> = T extends (first: any, ...rest: infer R) => any ? R : never;
type FirstParameter<T extends Fn> = T extends (first: infer A, ...rest: any[]) => any ? A : never;

/**
 * Partially applies a multi-arg function by pre-filling every argument
 * except the first — returning a unary function useful for pipeline composition.
 *
 * @example
 * ```ts
 * const double = (num: number) => num * 2;
 * const doubleAll = partial(select, double);
 * doubleAll([1, 2, 3]); // [2, 4, 6]
 *
 * // In a pipe
 * pipe(partial(select, (x: number) => x > 1 ? x * 2 : null))([1, 2, 3]); // [4, 6]
 * ```
 *
 * @param callback - Any function whose first argument is the collection.
 * @param args - The remaining arguments to pre-apply.
 * @returns A unary function `(collection) => ReturnType<F>`.
 */
export const partial = <F extends Fn>(callback: F, ...args: RemoveFirstParameter<F>) => {
  return (collection: FirstParameter<F>) => callback(collection, ...args);
};

Features

  • Isomorphic: Works in both Browser and Node.js.
  • Auto-Currying: Pre-binds transformation logic and waits for the data.
  • Composition Friendly: Perfect for use with pipe, compose, or native .map()/.filter() calls.
  • Type-safe: Properly narrows types for the resulting unary function.

API

ts
function fp<T, R>(callback: (...args: any[]) => any, ...args: any[]): (data: T[]) => R;

Parameters

  • callback: A toolkit function that supports FP mode (most array/collection utilities).
  • ...args: The configuration arguments for the callback (excluding the data array).

Returns

  • A new function that accepts a single argument: the data array to be processed.

Examples

Reusable Transformations

ts
import { fp, map, chunk } from '@vielzeug/toolkit';

// Create a reusable 'doubler' function
const doubleAll = fp(map, (n: number) => n * 2);

doubleAll([1, 2, 3]); // [2, 4, 6]
doubleAll([10, 20]); // [20, 40]

Within a Pipeline

ts
import { fp, pipe, map, filter } from '@vielzeug/toolkit';

const process = pipe(
  fp(filter, (n: number) => n > 10),
  fp(map, (n: number) => n * n),
);

process([5, 12, 8, 20]); // [144, 400]

Implementation Notes

  • Only functions that have been specifically prepared for FP mode will work (they must support being called with ...args first).
  • Throws TypeError if the callback is not a function.
  • Performance is nearly identical to calling the original utility directly.

See Also

  • pipe: Compose multiple FP functions together.
  • curry: Manual currying for any custom function.