CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fp-ts

Functional programming library for TypeScript with higher-kinded types, algebraic data types, and type classes

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

record.mddocs/

Record Operations

Record operations provide functional utilities for working with JavaScript objects as immutable records (dictionaries). Records are key-value maps where keys are strings and values are of a consistent type.

Core Imports

import { record } from "fp-ts/lib/Record";
import { isEmpty, size, lookup, has } from "fp-ts/lib/Record";

Capabilities

Basic Operations

Essential operations for working with records.

/**
 * Calculate the number of key/value pairs in a record
 * @param d - Record to measure
 * @returns Number of key/value pairs
 */
function size<A>(d: Record<string, A>): number;

/**
 * Test whether a record is empty
 * @param d - Record to test
 * @returns true if record has no keys
 */
function isEmpty<A>(d: Record<string, A>): boolean;

/**
 * Test whether a record has a key
 * @param k - Key to test for
 * @param d - Record to test
 * @returns true if key exists in record
 */
function has<A>(k: string, d: Record<string, A>): boolean;

/**
 * Lookup value by key, returning Option
 * @param k - Key to lookup
 * @param d - Record to search in
 * @returns Option containing value if key exists
 */
function lookup<A>(k: string, d: Record<string, A>): Option<A>;

Usage Examples:

import { size, isEmpty, has, lookup } from "fp-ts/lib/Record";

const person = { name: "Alice", age: 30 };

const recordSize = size(person); // 2
const empty = isEmpty({}); // true
const hasName = has("name", person); // true
const maybeName = lookup("name", person); // some("Alice")
const maybeEmail = lookup("email", person); // none

Record Construction and Modification

Create and modify records immutably.

/**
 * Create empty record
 */
const empty: Record<string, never>;

/**
 * Create record with single key-value pair
 * @param k - Key
 * @param a - Value
 * @returns Record with single entry
 */
function singleton<A>(k: string, a: A): Record<string, A>;

/**
 * Insert or update key-value pair
 * @param k - Key to insert
 * @param a - Value to insert
 * @param d - Record to modify
 * @returns New record with key-value pair added/updated
 */
function insert<A>(k: string, a: A, d: Record<string, A>): Record<string, A>;

/**
 * Remove key from record
 * @param k - Key to remove
 * @param d - Record to modify
 * @returns New record with key removed
 */
function remove<A>(k: string, d: Record<string, A>): Record<string, A>;

/**
 * Remove key and return both value and remaining record
 * @param k - Key to remove
 * @param d - Record to modify
 * @returns Option of tuple [value, remaining record]
 */
function pop<A>(k: string, d: Record<string, A>): Option<[A, Record<string, A>]>;

/**
 * Update value at key using function
 * @param k - Key to update
 * @param f - Function to transform value
 * @param d - Record to modify
 * @returns New record with value updated
 */
function modifyAt<A>(k: string, f: (a: A) => A, d: Record<string, A>): Record<string, A>;

/**
 * Update value at key
 * @param k - Key to update
 * @param a - New value
 * @param d - Record to modify
 * @returns Option of new record if key exists
 */
function updateAt<A>(k: string, a: A, d: Record<string, A>): Option<Record<string, A>>;

/**
 * Delete key at specific position
 * @param k - Key to delete
 * @param d - Record to modify
 * @returns Option of new record if key exists
 */
function deleteAt<A>(k: string, d: Record<string, A>): Option<Record<string, A>>;

Transformation Operations

Transform records using functional operations.

/**
 * Map over record values
 * @param f - Function to transform values
 * @param d - Record to transform
 * @returns New record with transformed values
 */
function map<A, B>(f: (a: A) => B, d: Record<string, A>): Record<string, B>;

/**
 * Map over record values with key information
 * @param f - Function receiving key and value
 * @param d - Record to transform
 * @returns New record with transformed values
 */
function mapWithIndex<A, B>(f: (k: string, a: A) => B, d: Record<string, A>): Record<string, B>;

/**
 * Collect record entries into array
 * @param f - Function to transform key-value pairs
 * @param d - Record to collect from
 * @returns Array of transformed entries
 */
function collect<A, B>(f: (k: string, a: A) => B, d: Record<string, A>): Array<B>;

/**
 * Convert record to array of key-value pairs
 * @param d - Record to convert
 * @returns Array of [key, value] tuples
 */
function toArray<A>(d: Record<string, A>): Array<[string, A]>;

/**
 * Get array of record keys
 * @param d - Record to get keys from
 * @returns Array of keys
 */
function keys<A>(d: Record<string, A>): Array<string>;

/**
 * Convert record to unfoldable structure
 * @param unfoldable - Unfoldable instance
 * @param d - Record to convert
 * @returns Unfoldable structure containing key-value pairs
 */
function toUnfoldable<F>(unfoldable: Unfoldable<F>): <A>(d: Record<string, A>) => HKT<F, [string, A]>;

Filtering Operations

Filter records based on predicates.

/**
 * Filter record by predicate on values
 * @param predicate - Predicate to test values
 * @param d - Record to filter
 * @returns New record containing only entries where predicate is true
 */
function filter<A>(predicate: Predicate<A>, d: Record<string, A>): Record<string, A>;
function filter<A, B extends A>(refinement: Refinement<A, B>, d: Record<string, A>): Record<string, B>;

/**
 * Filter record by predicate on keys and values
 * @param predicate - Predicate receiving key and value
 * @param d - Record to filter
 * @returns New record containing only entries where predicate is true
 */
function filterWithIndex<A>(predicate: PredicateWithIndex<string, A>, d: Record<string, A>): Record<string, A>;
function filterWithIndex<A, B extends A>(refinement: RefinementWithIndex<string, A, B>, d: Record<string, A>): Record<string, B>;

/**
 * Transform and filter record in one step
 * @param f - Function returning Option of transformed value
 * @param d - Record to transform and filter
 * @returns New record with transformed values where function returned Some
 */
function filterMap<A, B>(f: (a: A) => Option<B>, d: Record<string, A>): Record<string, B>;

/**
 * Transform and filter record with key information
 * @param f - Function receiving key and value, returning Option
 * @param d - Record to transform and filter
 * @returns New record with transformed values where function returned Some
 */
function filterMapWithIndex<A, B>(f: (k: string, a: A) => Option<B>, d: Record<string, A>): Record<string, B>;

/**
 * Partition record into two records based on predicate
 * @param predicate - Predicate to test values
 * @param d - Record to partition
 * @returns Separated object with left (false) and right (true) records
 */
function partition<A>(predicate: Predicate<A>, d: Record<string, A>): Separated<Record<string, A>, Record<string, A>>;
function partition<A, B extends A>(refinement: Refinement<A, B>, d: Record<string, A>): Separated<Record<string, A>, Record<string, B>>;

/**
 * Partition record with key information
 * @param predicate - Predicate receiving key and value
 * @param d - Record to partition
 * @returns Separated object with left (false) and right (true) records
 */
function partitionWithIndex<A>(predicate: PredicateWithIndex<string, A>, d: Record<string, A>): Separated<Record<string, A>, Record<string, A>>;

/**
 * Partition and transform record based on Either-returning function
 * @param f - Function returning Either
 * @param d - Record to partition and transform
 * @returns Separated object with left and right transformed records
 */
function partitionMap<A, B, C>(f: (a: A) => Either<B, C>, d: Record<string, A>): Separated<Record<string, B>, Record<string, C>>;

/**
 * Partition and transform record with key information
 * @param f - Function receiving key and value, returning Either
 * @param d - Record to partition and transform
 * @returns Separated object with left and right transformed records
 */
function partitionMapWithIndex<A, B, C>(f: (k: string, a: A) => Either<B, C>, d: Record<string, A>): Separated<Record<string, B>, Record<string, C>>;

Folding Operations

Reduce records to single values.

/**
 * Left fold over record values
 * @param b - Initial accumulator value
 * @param f - Folding function
 * @param d - Record to fold
 * @returns Final accumulated value
 */
function reduce<A, B>(b: B, f: (b: B, a: A) => B, d: Record<string, A>): B;

/**
 * Left fold with key information
 * @param b - Initial accumulator value
 * @param f - Folding function receiving key, accumulator, and value
 * @param d - Record to fold
 * @returns Final accumulated value
 */
function reduceWithIndex<A, B>(b: B, f: (k: string, b: B, a: A) => B, d: Record<string, A>): B;

/**
 * Right fold over record values
 * @param b - Initial accumulator value
 * @param f - Folding function
 * @param d - Record to fold
 * @returns Final accumulated value
 */
function reduceRight<A, B>(b: B, f: (a: A, b: B) => B, d: Record<string, A>): B;

/**
 * Right fold with key information
 * @param b - Initial accumulator value
 * @param f - Folding function receiving key, value, and accumulator
 * @param d - Record to fold
 * @returns Final accumulated value
 */
function reduceRightWithIndex<A, B>(b: B, f: (k: string, a: A, b: B) => B, d: Record<string, A>): B;

/**
 * Map each value to a monoid and combine results
 * @param M - Monoid instance for combining results
 * @param f - Function to map values to monoid
 * @param d - Record to fold
 * @returns Combined monoid value
 */
function foldMap<M>(M: Monoid<M>): <A>(f: (a: A) => M, d: Record<string, A>) => M;

/**
 * Map each key-value pair to a monoid and combine results
 * @param M - Monoid instance for combining results
 * @param f - Function to map key-value pairs to monoid
 * @param d - Record to fold
 * @returns Combined monoid value
 */
function foldMapWithIndex<M>(M: Monoid<M>): <A>(f: (k: string, a: A) => M, d: Record<string, A>) => M;

Set Operations

Operations treating records as sets.

/**
 * Test whether first record is subrecord of second
 * @param E - Equality instance for values
 * @param d1 - Potential sub-record
 * @param d2 - Potential super-record
 * @returns true if d1 is subrecord of d2
 */
function isSubrecord<A>(E: Eq<A>): (d1: Record<string, A>, d2: Record<string, A>) => boolean;

/**
 * Get union of two records (values from second record override first)
 * @param d1 - First record
 * @param d2 - Second record
 * @returns New record containing keys from both records
 */
function union<A>(d1: Record<string, A>, d2: Record<string, A>): Record<string, A>;

/**
 * Get intersection of two records
 * @param d1 - First record
 * @param d2 - Second record
 * @returns New record containing only keys present in both records
 */
function intersection<A>(d1: Record<string, A>, d2: Record<string, A>): Record<string, A>;

/**
 * Get difference of two records (keys in first but not second)
 * @param d1 - First record
 * @param d2 - Second record
 * @returns New record containing keys from d1 not in d2
 */
function difference<A>(d1: Record<string, A>, d2: Record<string, A>): Record<string, A>;

Type Class Instances

Record implements various type class instances.

/**
 * Equality instance for Record
 * @param E - Equality instance for values
 * @returns Equality instance that compares records key-wise
 */
function getEq<A>(E: Eq<A>): Eq<Record<string, A>>;

/**
 * Show instance for Record
 * @param S - Show instance for values
 * @returns Show instance that displays record contents
 */
function getShow<A>(S: Show<A>): Show<Record<string, A>>;

/**
 * Monoid instance for Record (union with semigroup for values)
 * @param S - Semigroup instance for values
 * @returns Monoid instance for records
 */
function getMonoid<A>(S: Semigroup<A>): Monoid<Record<string, A>>;

/**
 * Record instance providing Functor, Foldable, Traversable operations
 */
const record: FunctorWithIndex1<URI, string> &
  FoldableWithIndex1<URI, string> &
  TraversableWithIndex1<URI, string> &
  Compactable1<URI> &
  FilterableWithIndex1<URI, string> &
  Witherable1<URI>;

Common Patterns

Object Processing Pipeline

import { pipe } from "fp-ts/lib/pipeable";
import { map, filter, collect } from "fp-ts/lib/Record";

const users = {
  alice: { age: 25, active: true },
  bob: { age: 30, active: false },
  charlie: { age: 35, active: true }
};

const activeUserAges = pipe(
  users,
  filter((user) => user.active),
  map((user) => user.age),
  collect((name, age) => ({ name, age }))
);
// Result: [{ name: "alice", age: 25 }, { name: "charlie", age: 35 }]

Safe Object Access

import { lookup, map } from "fp-ts/lib/Record";
import { getOrElse } from "fp-ts/lib/Option";

const config = { host: "localhost", port: 3000 };

const host = pipe(
  lookup("host", config),
  getOrElse(() => "127.0.0.1")
);

const port = pipe(
  lookup("port", config),
  map(String),
  getOrElse(() => "8080")
);

Record Transformation and Validation

import { traverse } from "fp-ts/lib/Record";
import { option } from "fp-ts/lib/Option";
import { parseNumber } from "./utils";

const stringNumbers = { a: "1", b: "2", c: "not-a-number" };

const maybeNumbers = traverse(option)(parseNumber)(stringNumbers);
// Result: none (because "not-a-number" fails to parse)

const validNumbers = { a: "1", b: "2", c: "3" };
const parsedNumbers = traverse(option)(parseNumber)(validNumbers);
// Result: some({ a: 1, b: 2, c: 3 })

Types

// Record is the native JavaScript object type
// Used as Record<string, A> for objects with string keys and values of type A

// URI for type-level programming
const URI = 'Record';
type URI = typeof URI;

// Key constraint for records
type RecordKey = string;

// Separated type for partition operations
interface Separated<E, A> {
  left: E;
  right: A;
}

// Predicate and Refinement types
type Predicate<A> = (a: A) => boolean;
type Refinement<A, B extends A> = (a: A) => a is B;
type PredicateWithIndex<I, A> = (i: I, a: A) => boolean;
type RefinementWithIndex<I, A, B extends A> = (i: I, a: A) => a is B;

docs

algebraic.md

array.md

either.md

function.md

index.md

io.md

option.md

pipeable.md

record.md

task-either.md

task.md

type-classes.md

tile.json