Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

Record

Works with plain JavaScript records as immutable key/value dictionaries.

A record is an object whose keys are strings or symbols. This module includes helpers for construction, lookup, updates, mapping, filtering, folding, set-like combination, and typed conversions between records and iterable entries. Helpers that change values return new records instead of mutating the input.

45 exports Since v2.0.0 Source

Combining

Merges two records, preserving only the entries that are unique to each record. Keys that exist in both records are excluded from the result.

Signature

declare const difference: {
<K1 extends string, B>(that: ReadonlyRecord<K1, B>): <K0 extends string, A>(self: ReadonlyRecord<K0, A>) => Record<K0 | K1, A | B>;
<K0 extends string, A, K1 extends string, B>(self: ReadonlyRecord<K0, A>, that: ReadonlyRecord<K1, B>): Record<K0 | K1, A | B>;
}

Example Keeping keys unique to each record

import { Record } from "effect"
Record.difference({ a: 1, b: 2 }, { b: 3, c: 4 }) // => { a: 1, c: 4 }

Merges two records, retaining only the entries that exist in both records. For intersecting keys, the provided combine function is used to merge the values.

Signature

declare const intersection: {
<K1 extends string, A, B, C>(that: ReadonlyRecord<K1, B>, combine: (selfValue: A, thatValue: B) => C): <K0 extends string>(self: ReadonlyRecord<K0, A>) => Record<ReadonlyRecord.IntersectKeys<K0, K1>, C>;
<K0 extends string, A, K1 extends string, B, C>(self: ReadonlyRecord<K0, A>, that: ReadonlyRecord<K1, B>, combine: (selfValue: A, thatValue: B) => C): Record<ReadonlyRecord.IntersectKeys<K0, K1>, C>;
}

Example Merging intersecting keys

import { Record } from "effect"
Record.intersection({ a: 1, b: 2 }, { b: 3, c: 4 }, (a, b) => a + b) // => { b: 5 }

Creates a Reducer whose combine operation intersects two records and combines values for keys present in both records.

When to use

Use to build a Reducer that combines records by retaining only keys shared by both inputs and combining matching values with a Combiner.

Gotchas

The reducer's initialValue is an empty record. Because intersection with an empty record is empty, the default combineAll folds from {} and therefore produces {} for ordinary non-empty inputs.

See

  • makeReducerUnion for a reducer that preserves keys from either input record
  • intersection for applying the shared-key merge to one pair of records

Signature

declare function makeReducerIntersection<K extends string, A>(combiner: Combiner<A>): Reducer<Record<K, A>>

Creates a Reducer for combining Records using union, with values for keys that exist in both records combined using the provided Combiner.

When to use

Use to build a reusable reducer for accumulating many records into one union-shaped record, preserving keys from every input and combining overlapping values with the supplied combiner.

Details

The returned reducer uses Record.union for combine and an empty record as initialValue, so the default combineAll folds from {} and accumulates keys from each input record.

See

  • union for one-off record merging with the same union semantics
  • makeReducerIntersection for a reducer that keeps only keys present on both sides

Signature

declare function makeReducerUnion<K extends string, A>(combiner: Combiner<A>): Reducer<Record<K, A>>
Since v2.0.0

Merges two records, preserving entries that exist in either of the records. For keys that exist in both records, the provided combine function is used to merge the values.

Signature

declare const union: {
<K1 extends string, A, B, C>(that: ReadonlyRecord<K1, B>, combine: (selfValue: A, thatValue: B) => C): <K0 extends string>(self: ReadonlyRecord<K0, A>) => Record<K0 | K1, A | B | C>;
<K0 extends string, A, K1 extends string, B, C>(self: ReadonlyRecord<K0, A>, that: ReadonlyRecord<K1, B>, combine: (selfValue: A, thatValue: B) => C): Record<K0 | K1, A | B | C>;
}

Example Merging records with union

import { Record } from "effect"
Record.union({ a: 1, b: 2 }, { b: 3, c: 4 }, (a, b) => a + b) // => { a: 1, b: 5, c: 4 }

Constructors

Since v2.0.0

Creates a new, empty record.

Signature

declare function empty<K extends string | symbol = never, V = never>(): Record<ReadonlyRecord.NonLiteralKey<K>, V>

Example Creating an empty record

import { Record } from "effect"
// Create an empty record
const emptyRecord = Record.empty<string, number>()
emptyRecord // => {}
// The type ensures type safety for future operations
Record.set(emptyRecord, "count", 42) // => { count: 42 }

Builds a record from an iterable of key-value pairs.

Details

If there are conflicting keys when using fromEntries, the last occurrence of the key/value pair will overwrite the previous ones. So the resulting record will only have the value of the last occurrence of each key.

Signature

declare const fromEntries: <Entry extends readonly [string | symbol, any]>(entries: Iterable<Entry>) => Record<ReadonlyRecord.NonLiteralKey<Entry[0]>, Entry[1]>

Example Building a record from entries

import { Record } from "effect"
Record.fromEntries([["a", 1], ["b", 2]]) // => { a: 1, b: 2 }

Creates a new record from an iterable, utilizing the provided function to determine the key for each element.

Signature

declare const fromIterableBy: {
<A, K extends string | symbol>(f: (a: A) => K): (items: Iterable<A>) => Record<ReadonlyRecord.NonLiteralKey<K>, A>;
<A, K extends string | symbol>(items: Iterable<A>, f: (a: A) => K): Record<ReadonlyRecord.NonLiteralKey<K>, A>;
}

Example Building a record keyed by iterable values

import { Record } from "effect"
const users = [
{ id: "2", name: "name2" },
{ id: "1", name: "name1" }
]
Record.fromIterableBy(
users,
(user) => user.id
) // => { "1": { id: "1", name: "name1" }, "2": { id: "2", name: "name2" } }

Takes an iterable and a projection function and returns a record. The projection function maps each value of the iterable to a tuple of a key and a value, which is then added to the resulting record.

Signature

declare const fromIterableWith: {
<A, K extends string | symbol, B>(f: (a: A) => readonly [K, B]): (self: Iterable<A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B>;
<A, K extends string | symbol, B>(self: Iterable<A>, f: (a: A) => readonly [K, B]): Record<ReadonlyRecord.NonLiteralKey<K>, B>;
}

Example Building a record from mapped iterable values

import { Record } from "effect"
Record.fromIterableWith([1, 2, 3, 4], (a) => [String(a), a * 2]) // => { "1": 2, "2": 4, "3": 6, "4": 8 }

Create a non-empty record from a single element.

Signature

declare function singleton<K extends string | symbol, A>(key: K, value: A): Record<K, A>

Example Creating a singleton record

import { Record } from "effect"
Record.singleton("a", 1) // => { a: 1 }

Converting

Since v2.0.0

Transforms the values of a record into an Array with a custom mapping function.

Signature

declare const collect: {
<K extends string, A, B>(f: (key: K, a: A) => B): (self: ReadonlyRecord<K, A>) => Array<B>;
<K extends string, A, B>(self: ReadonlyRecord<K, A>, f: (key: K, a: A) => B): Array<B>;
}

Example Collecting mapped record values

import { Record } from "effect"
const x = { a: 1, b: 2, c: 3 }
Record.collect(x, (key, n) => [key, n]) // => [["a", 1], ["b", 2], ["c", 3]]

Takes a record and returns an array of tuples containing its keys and values.

Signature

declare const toEntries: <K extends string, A>(self: ReadonlyRecord<K, A>) => Array<[K, A]>

Example Converting a record to entries

import { Record } from "effect"
const x = { a: 1, b: 2, c: 3 }
Record.toEntries(x) // => [["a", 1], ["b", 2], ["c", 3]]

Filtering

Since v2.0.0

Selects properties from a record whose values match the given predicate.

Signature

declare const filter: {
<K extends string, A, B>(refinement: (a: NoInfer<A>, key: K) => a is B): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B>;
<K extends string, A>(predicate: (A: NoInfer<A>, key: K) => boolean): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, A>;
<K extends string, A, B>(self: ReadonlyRecord<K, A>, refinement: (a: A, key: K) => a is B): Record<ReadonlyRecord.NonLiteralKey<K>, B>;
<K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (a: A, key: K) => boolean): Record<ReadonlyRecord.NonLiteralKey<K>, A>;
}

Example Filtering record values

import { Record } from "effect"
const x = { a: 1, b: 2, c: 3, d: 4 }
Record.filter(x, (n) => n > 2) // => { c: 3, d: 4 }

Transforms a record by applying the function f to each key and value in the original record. If the function succeeds, the key-value pair is included in the output record.

Signature

declare const filterMap: {
<K extends string, A, B, X>(f: (input: A, key: K) => Result<B, X>): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B>;
<K extends string, A, B, X>(self: ReadonlyRecord<K, A>, f: (input: A, key: K) => Result<B, X>): Record<ReadonlyRecord.NonLiteralKey<K>, B>;
}

Example Filtering and mapping with Result

import { Record, Result } from "effect"
const x = { a: 1, b: 2, c: 3 }
const f = (a: number, key: string) => a > 2 ? Result.succeed(a * 2) : Result.failVoid
Record.filterMap(x, f) // => { c: 6 }

Returns a new record containing only the Err values from a record of Result values, preserving the original keys.

Signature

declare function getFailures<K extends string, A, E>(self: ReadonlyRecord<K, Result<A, E>>): Record<ReadonlyRecord.NonLiteralKey<K>, E>

Example Extracting Result failures

import { Record, Result } from "effect"
Record.getFailures({
a: Result.succeed(1),
b: Result.fail("err"),
c: Result.succeed(2)
}) // => { b: "err" }
Since v2.0.0

Returns a new record containing only the Some values from a record of Option values, preserving the original keys.

Signature

declare const getSomes: <K extends string, A>(self: ReadonlyRecord<K, Option.Option<A>>) => Record<ReadonlyRecord.NonLiteralKey<K>, A>

Example Extracting Some values

import { Option, Record } from "effect"
Record.getSomes({ a: Option.some(1), b: Option.none(), c: Option.some(2) }) // => { a: 1, c: 2 }

Returns a new record containing only the Ok values from a record of Result values, preserving the original keys.

Signature

declare function getSuccesses<K extends string, A, E>(self: ReadonlyRecord<K, Result<A, E>>): Record<string, A>

Example Extracting Result successes

import { Record, Result } from "effect"
Record.getSuccesses({
a: Result.succeed(1),
b: Result.fail("err"),
c: Result.succeed(2)
}) // => { a: 1, c: 2 }

Applies a function to each record entry and partitions the returned Result values into two records.

Details

Success values are collected in the first record, and failure values are collected in the second record, preserving the original keys.

Signature

declare const partition: {
<K extends string, A, B, C>(f: (input: A, key: K) => Result<C, B>): (self: ReadonlyRecord<K, A>) => [passes: Record<NonLiteralKey<K>, C>, fails: Record<NonLiteralKey<K>, B>];
<K extends string, A, B, C>(self: ReadonlyRecord<K, A>, f: (input: A, key: K) => Result<C, B>): [passes: Record<NonLiteralKey<K>, C>, fails: Record<NonLiteralKey<K>, B>];
}

Example Partitioning with Result

import { Record, Result } from "effect"
const x = { a: 1, b: 2, c: 3 }
const f = (n: number) => (n % 2 === 0 ? Result.succeed(n) : Result.fail(n))
Record.partition(x, f) // => [{ b: 2 }, { a: 1, c: 3 }]
Since v2.0.0

Partitions a record of Result values into two separate records, one with the success values and one with the failure values.

Signature

declare const separate: <K extends string, A, B>(self: ReadonlyRecord<K, Result<B, A>>) => [Record<ReadonlyRecord.NonLiteralKey<K>, B>, Record<ReadonlyRecord.NonLiteralKey<K>, A>]

Example Separating Result values

import { Record, Result } from "effect"
Record.separate({ a: Result.fail("e"), b: Result.succeed(1) }) // => [{ b: 1 }, { a: "e" }]

Folding

Since v2.0.0

Reduces a record to a single value by combining its entries with a specified function.

Signature

declare const reduce: {
<Z, V, K extends string>(zero: Z, f: (accumulator: Z, value: V, key: K) => Z): (self: ReadonlyRecord<K, V>) => Z;
<K extends string, V, Z>(self: ReadonlyRecord<K, V>, zero: Z, f: (accumulator: Z, value: V, key: K) => Z): Z;
}

Example Reducing record values

import { Record } from "effect"
Record.reduce({ a: 1, b: 2, c: 3 }, 0, (acc, value) => acc + value) // => 6

Getters

Since v2.0.0

Retrieves a value at a particular key from a record safely, returning it wrapped in an Option.

Signature

declare const get: {
<K extends string | symbol>(key: NoInfer<K>): <A>(self: ReadonlyRecord<K, A>) => Option<A>;
<K extends string | symbol, A>(self: ReadonlyRecord<K, A>, key: NoInfer<K>): Option<A>;
}

Example Getting a value as an Option

import { Option, Record as R } from "effect"
const person: Record<string, unknown> = { name: "John Doe", age: 35 }
R.get(person, "name") // => Option.some("John Doe")
R.get(person, "email") // => Option.none()
Since v2.0.0

Retrieves the keys of a given record as an array.

Signature

declare function keys<K extends string | symbol, A>(self: ReadonlyRecord<K, A>): Array<K & string>

Example Getting record keys

import { Record } from "effect"
Record.keys({ a: 1, b: 2, c: 3 }) // => ["a", "b", "c"]
Since v2.0.0

Returns the number of key/value pairs in a record.

Signature

declare function size<K extends string, A>(self: ReadonlyRecord<K, A>): number

Example Getting the record size

import { Record } from "effect"
Record.size({ a: "a", b: 1, c: true }) // => 3
Since v2.0.0

Retrieves the values of a given record as an array.

Signature

declare function values<K extends string, A>(self: ReadonlyRecord<K, A>): Array<A>

Example Getting record values

import { Record } from "effect"
Record.values({ a: 1, b: 2, c: 3 }) // => [1, 2, 3]

Guards

Since v2.0.0

Checks whether all entries in a record meet a specific condition.

Signature

declare const every: {
<A, K extends string, B>(refinement: (value: A, key: K) => value is B): (self: ReadonlyRecord<K, A>) => self is ReadonlyRecord<K, B>;
<A, K extends string>(predicate: (value: A, key: K) => boolean): (self: ReadonlyRecord<K, A>) => boolean;
<A, K extends string, B>(self: ReadonlyRecord<K, A>, refinement: (value: A, key: K) => value is B): self is ReadonlyRecord<K, B>;
<K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (value: A, key: K) => boolean): boolean;
}

Example Checking every record value

import { Record } from "effect"
Record.every({ a: 1, b: 2 }, (n) => n > 0) // => true
Record.every({ a: 1, b: -1 }, (n) => n > 0) // => false

Determines if a readonly record is empty.

Signature

declare const isEmptyReadonlyRecord: <K extends string, A>(self: ReadonlyRecord<K, A>) => self is ReadonlyRecord<K, never>

Example Checking for an empty readonly record

import { Record } from "effect"
Record.isEmptyReadonlyRecord({}) // => true
Record.isEmptyReadonlyRecord({ a: 3 }) // => false

Determines if a mutable record is empty.

Signature

declare function isEmptyRecord<K extends string, A>(self: Record<K, A>): self is Record<K, never>

Example Checking for an empty record

import { Record } from "effect"
Record.isEmptyRecord({}) // => true
Record.isEmptyRecord({ a: 3 }) // => false

Instances

Create an Equivalence for records using the provided Equivalence for values. Two records are considered equivalent if they have the same keys and their corresponding values are equivalent.

Signature

declare function makeEquivalence<K extends string, A>(equivalence: Equivalence<A>): Equivalence<ReadonlyRecord<K, A>>

Example Comparing records with a value equivalence

import { Equal, Record } from "effect"
const recordEquivalence = Record.makeEquivalence(Equal.asEquivalence<number>())
recordEquivalence({ a: 1, b: 2 }, { a: 1, b: 2 }) // => true
recordEquivalence({ a: 1, b: 2 }, { a: 1, b: 3 }) // => false

Mapping

Since v2.0.0

Maps a record into another record by applying a transformation function to each of its values.

Signature

declare const map: {
<K extends string, A, B>(f: (a: A, key: NoInfer<K>) => B): (self: ReadonlyRecord<K, A>) => Record<K, B>;
<K extends string, A, B>(self: ReadonlyRecord<K, A>, f: (a: A, key: NoInfer<K>) => B): Record<K, B>;
}

Example Mapping record values

import { Record } from "effect"
const f = (n: number) => `-${n}`
Record.map({ a: 3, b: 5 }, f) // => { a: "-3", b: "-5" }
const g = (n: number, key: string) => `${key.toUpperCase()}-${n}`
Record.map({ a: 3, b: 5 }, g) // => { a: "A-3", b: "B-5" }

Maps entries of a ReadonlyRecord using the provided function, allowing modification of both keys and corresponding values.

Signature

declare const mapEntries: {
<K extends string, A, K2 extends string, B>(f: (a: A, key: K) => readonly [K2, B]): (self: ReadonlyRecord<K, A>) => Record<K2, B>;
<K extends string, A, K2 extends string, B>(self: ReadonlyRecord<K, A>, f: (a: A, key: K) => [K2, B]): Record<K2, B>;
}

Example Mapping record entries

import { Record } from "effect"
Record.mapEntries({ a: 3, b: 5 }, (a, key) => [key.toUpperCase(), a + 1]) // => { A: 4, B: 6 }
Since v2.0.0

Maps the keys of a ReadonlyRecord while preserving the corresponding values.

Signature

declare const mapKeys: {
<K extends string, A, K2 extends string>(f: (key: K, a: A) => K2): (self: ReadonlyRecord<K, A>) => Record<K2, A>;
<K extends string, A, K2 extends string>(self: ReadonlyRecord<K, A>, f: (key: K, a: A) => K2): Record<K2, A>;
}

Example Mapping record keys

import { Record } from "effect"
Record.mapKeys({ a: 3, b: 5 }, (key) => key.toUpperCase()) // => { A: 3, B: 5 }

Models

Since v2.0.0

Represents a readonly record with keys of type K and values of type A. This is the foundational type for immutable key-value mappings in Effect.

Signature

type ReadonlyRecord<in out K extends string | symbol, out A> = { [P in K]: A }

Example Defining a readonly record type

import type { Record } from "effect"
// Creating a readonly record type
type UserRecord = Record.ReadonlyRecord<"name" | "age", string | number>
const user: UserRecord = {
name: "John",
age: 30
}
user // => { name: "John", age: 30 }

Mutations

Mutates a record by assigning a value to a property.

When to use

Use when incrementally constructing a new record and copying it for every property would be unnecessary.

Gotchas

This function mutates self. When key is "__proto__", it creates an own data property instead of changing the object's prototype.

See

  • set for an immutable update

Signature

declare const assignProperty: (self: object, key: PropertyKey, value: unknown) => void

Example Assigning an external key safely

import { Record } from "effect"
const key: string = "__proto__" // Assume this comes from external input
const value = { polluted: true }
const unsafe: Record<string, unknown> = {}
unsafe[key] = value
Object.getPrototypeOf(unsafe) === value // => true
const safe: Record<string, unknown> = {}
Record.assignProperty(safe, key, value)
Object.getPrototypeOf(safe) === Object.prototype // => true
safe[key] === value // => true
Since v2.0.0

Applies a function to the element at the specified key safely, creating a new record, or return Option.none() if the key doesn't exist.

Signature

declare const modify: {
<K extends string | symbol, A, B>(key: NoInfer<K>, f: (a: A) => B): (self: ReadonlyRecord<K, A>) => Option<Record<K, A | B>>;
<K extends string | symbol, A, B>(self: ReadonlyRecord<K, A>, key: NoInfer<K>, f: (a: A) => B): Option<Record<K, A | B>>;
}

Example Modifying a value at a key

import { Option, Record } from "effect"
const f = (x: number) => x * 2
const input: Record<string, number> = { a: 3 }
Record.modify(input, "a", f) // => Option.some({ a: 6 })
Record.modify(input, "b", f) // => Option.none()
Since v2.0.0

Retrieves the value of the property with the given key from a record safely and returns an Option of a tuple with the value and the record with the removed property. If the key is not present, returns Option.none().

Signature

declare const pop: {
<K extends string | symbol, X extends string | symbol>(key: X): <A>(self: ReadonlyRecord<K, A>) => Option<[A, Record<Exclude<K, X>, A>]>;
<K extends string | symbol, A, X extends string | symbol>(self: ReadonlyRecord<K, A>, key: X): Option<[A, Record<Exclude<K, X>, A>]>;
}

Example Popping a value and removing its key

import { Option, Record } from "effect"
const input: Record<string, number> = { a: 1, b: 2 }
Record.pop(input, "a") // => Option.some([1, { b: 2 }])
Record.pop(input, "c") // => Option.none()
Since v2.0.0

Removes a key from a record.

When to use

Use to create a shallow copy of a record without one property.

Details

If the key is not present, the result is still a shallow copy of the original record.

Signature

declare const remove: {
<K extends string | symbol, X extends string | symbol>(key: X): <A>(self: ReadonlyRecord<K, A>) => Record<Exclude<K, X>, A>;
<K extends string | symbol, A, X extends string | symbol>(self: ReadonlyRecord<K, A>, key: X): Record<Exclude<K, X>, A>;
}

Example Removing a key

import { Record } from "effect"
Record.remove({ a: 1, b: 2 }, "a") // => { b: 2 }
Since v2.0.0

Replaces the value at an existing key safely and returns the updated record in Option.some.

Details

If the key is not present, returns Option.none() and leaves the record unchanged.

Signature

declare const replace: {
<K extends string | symbol, B>(key: NoInfer<K>, b: B): <A>(self: ReadonlyRecord<K, A>) => Option<Record<K, B | A>>;
<K extends string | symbol, A, B>(self: ReadonlyRecord<K, A>, key: NoInfer<K>, b: B): Option<Record<K, A | B>>;
}

Example Replacing a value at a key

import { Option, Record } from "effect"
Record.replace({ a: 1, b: 2, c: 3 }, "a", 10) // => Option.some({ a: 10, b: 2, c: 3 })
Record.replace(Record.empty<string>(), "a", 10) // => Option.none()
Since v2.0.0

Adds a new key-value pair or update an existing key's value in a record.

Signature

declare const set: {
<K extends string | symbol, K1 extends string | symbol, B>(key: K1, value: B): <A>(self: ReadonlyRecord<K, A>) => Record<K | K1, A | B>;
<K extends string | symbol, A, K1 extends string | symbol, B>(self: ReadonlyRecord<K, A>, key: K1, value: B): Record<K | K1, A | B>;
}

Example Setting a record value

import { Record } from "effect"
Record.set("a", 5)({ a: 1, b: 2 }) // => { a: 5, b: 2 }
Record.set("c", 5)({ a: 1, b: 2 }) // => { a: 1, b: 2, c: 5 }

Other

Namespace containing utility types for working with readonly records. These types help with type-level operations on record keys and values.

Example Using readonly record helper types

import type { Record } from "effect"
// Using NonLiteralKey to convert literal keys to generic types
type GenericKey = Record.ReadonlyRecord.NonLiteralKey<"foo" | "bar"> // string
// Using IntersectKeys to find common keys between record types
type CommonKeys = Record.ReadonlyRecord.IntersectKeys<"a" | "b", "b" | "c"> // "b"
"key" satisfies GenericKey
"b" satisfies CommonKeys

Predicates

Since v2.0.0

Checks whether a given key exists in a record.

Signature

declare const has: {
<K extends string | symbol>(key: NoInfer<K>): <A>(self: ReadonlyRecord<K, A>) => boolean;
<K extends string | symbol, A>(self: ReadonlyRecord<K, A>, key: NoInfer<K>): boolean;
}

Example Checking key membership

import { Record } from "effect"
Record.has({ a: 1, b: 2 }, "a") // => true
Record.has(Record.empty<string>(), "c") // => false

Checks whether the first record is a subrecord of the second record.

Details

Returns true when every key and value in self is also present in that. Values are compared with Effect equality via Equal.asEquivalence().

Signature

declare const isSubrecord: {
<K extends string, A>(that: ReadonlyRecord<K, A>): (self: ReadonlyRecord<K, A>) => boolean;
<K extends string, A>(self: ReadonlyRecord<K, A>, that: ReadonlyRecord<K, A>): boolean;
}

Example Checking subrecords

import { Record } from "effect"
Record.isSubrecord({ a: 1 } as Record<string, number>, { a: 1, b: 2 }) // => true
Record.isSubrecord({ a: 1, b: 2 }, { a: 1 } as Record<string, number>) // => false

Checks whether all the keys and values in one record are also found in another record. Uses the provided equivalence function to compare values.

Signature

declare function isSubrecordBy<A>(equivalence: Equivalence<A>): {
<K extends string>(that: ReadonlyRecord<K, A>): (self: ReadonlyRecord<K, A>) => boolean;
<K extends string>(self: ReadonlyRecord<K, A>, that: ReadonlyRecord<K, A>): boolean;
}

Example Checking subrecords with a custom equivalence

import { Equivalence, Record } from "effect"
const isSubrecord = Record.isSubrecordBy(
Equivalence.make<string>((self, that) => self.toLowerCase() === that.toLowerCase())
)
const required: Record.ReadonlyRecord<string, string> = { role: "Admin" }
const available: Record.ReadonlyRecord<string, string> = {
role: "admin",
status: "active"
}
isSubrecord(required, available) // => true
isSubrecord({ role: "Admin", status: "inactive" }, available) // => false
isSubrecord(required, { role: "editor", status: "active" }) // => false
Since v2.0.0

Checks whether any entry in a record meets a specific condition.

Signature

declare const some: {
<A, K extends string>(predicate: (value: A, key: K) => boolean): (self: ReadonlyRecord<K, A>) => boolean;
<K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (value: A, key: K) => boolean): boolean;
}

Example Checking for any matching value

import { Record } from "effect"
Record.some({ a: 1, b: 2 }, (n) => n > 1) // => true
Record.some({ a: 1, b: 2 }, (n) => n > 2) // => false

Searching

Since v3.14.0

Returns the first entry that satisfies the specified predicate, or None if no such entry exists.

Signature

declare const findFirst: {
<K extends string | symbol, V, V2>(refinement: (value: NoInfer<V>, key: NoInfer<K>) => value is V2): (self: ReadonlyRecord<K, V>) => Option<[K, V2]>;
<K extends string | symbol, V>(predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean): (self: ReadonlyRecord<K, V>) => Option<[K, V]>;
<K extends string | symbol, V, V2>(self: ReadonlyRecord<K, V>, refinement: (value: NoInfer<V>, key: NoInfer<K>) => value is V2): Option<[K, V2]>;
<K extends string | symbol, V>(self: ReadonlyRecord<K, V>, predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean): Option<[K, V]>;
}

Example Finding the first matching entry

import { Option, Record } from "effect"
const record = { a: 1, b: 2, c: 3 }
Record.findFirst(
record,
(value, key) => value > 1 && key !== "b"
) // => Option.some(["c", 3])

Utility Types

Type lambda for readonly records, used in higher-kinded type operations. This enables records to work with generic type constructors and functors.

Signature

interface ReadonlyRecordTypeLambda<K extends string = string> extends TypeLambda {
readonly type: ReadonlyRecord<K, this["Target"]>;
}

Example Applying a readonly record type lambda

import type { HKT, Record } from "effect"
type Settings = HKT.Kind<
Record.ReadonlyRecordTypeLambda<"port" | "retries">,
never,
never,
never,
number
>
const defaults: Settings = {
port: 3000,
retries: 3
}
defaults // => { port: 3000, retries: 3 }