Record.ts
Record.ts overview
Section titled “Record.ts overview”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.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”- combining
- constructors
- converting
- elements
- filtering
- folding
- getters
- guards
- instances
- mapping
- models
- mutations
- predicates
- type lambdas
- utils
combining
Section titled “combining”difference
Section titled “difference”Merges two records, preserving only the entries that are unique to each record. Keys that exist in both records are excluded from the result.
Example (Keeping keys unique to each record)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.difference({ a: 1, b: 2 }, { b: 3, c: 4 }), { a: 1, c: 4 })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>}Since v2.0.0
intersection
Section titled “intersection”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.
Example (Merging intersecting keys)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.intersection({ a: 1, b: 2 }, { b: 3, c: 4 }, (a, b) => a + b), { b: 5 })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>}Since v2.0.0
makeReducerIntersection
Section titled “makeReducerIntersection”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
makeReducerUnionfor a reducer that preserves keys from either input recordintersectionfor applying the shared-key merge to one pair of records
Signature
declare const makeReducerIntersection: <K extends string, A>( combiner: Combiner.Combiner<A>) => Reducer.Reducer<Record<K, A>>Since v4.0.0
makeReducerUnion
Section titled “makeReducerUnion”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
unionfor one-off record merging with the same union semanticsmakeReducerIntersectionfor a reducer that keeps only keys present on both sides
Signature
declare const makeReducerUnion: <K extends string, A>(combiner: Combiner.Combiner<A>) => Reducer.Reducer<Record<K, A>>Since v4.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.
Example (Merging records with union)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.union({ a: 1, b: 2 }, { b: 3, c: 4 }, (a, b) => a + b), { a: 1, b: 5, c: 4 })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>}Since v2.0.0
constructors
Section titled “constructors”Creates a new, empty record.
Example (Creating an empty record)
import { Record } from "effect"
// Create an empty recordconst emptyRecord = Record.empty<string, number>()console.log(emptyRecord) // {}
// The type ensures type safety for future operationsconst withValue = Record.set(emptyRecord, "count", 42)console.log(withValue) // { count: 42 }Signature
declare const empty: <K extends string | symbol = never, V = never>() => Record<ReadonlyRecord.NonLiteralKey<K>, V>Since v2.0.0
fromEntries
Section titled “fromEntries”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.
Example (Building a record from entries)
import { Record } from "effect"import * as assert from "node:assert"
const input: Array<[string, number]> = [ ["a", 1], ["b", 2]]
assert.deepStrictEqual(Record.fromEntries(input), { a: 1, b: 2 })Signature
declare const fromEntries: <Entry extends readonly [string | symbol, any]>( entries: Iterable<Entry>) => Record<ReadonlyRecord.NonLiteralKey<Entry[0]>, Entry[1]>Since v2.0.0
fromIterableBy
Section titled “fromIterableBy”Creates a new record from an iterable, utilizing the provided function to determine the key for each element.
Example (Building a record keyed by iterable values)
import { Record } from "effect"import * as assert from "node:assert"
const users = [ { id: "2", name: "name2" }, { id: "1", name: "name1" }]
assert.deepStrictEqual( Record.fromIterableBy(users, (user) => user.id), { "2": { id: "2", name: "name2" }, "1": { id: "1", name: "name1" } })Signature
declare const fromIterableBy: <A, K extends string | symbol>( items: Iterable<A>, f: (a: A) => K) => Record<ReadonlyRecord.NonLiteralKey<K>, A>Since v2.0.0
fromIterableWith
Section titled “fromIterableWith”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.
Example (Building a record from mapped iterable values)
import { Record } from "effect"import * as assert from "node:assert"
const input = [1, 2, 3, 4]
assert.deepStrictEqual( Record.fromIterableWith(input, (a) => [String(a), a * 2]), { "1": 2, "2": 4, "3": 6, "4": 8 })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>}Since v2.0.0
singleton
Section titled “singleton”Create a non-empty record from a single element.
Example (Creating a singleton record)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.singleton("a", 1), { a: 1 })Signature
declare const singleton: <K extends string | symbol, A>(key: K, value: A) => Record<K, A>Since v2.0.0
converting
Section titled “converting”collect
Section titled “collect”Transforms the values of a record into an Array with a custom mapping function.
Example (Collecting mapped record values)
import { Record } from "effect"import * as assert from "node:assert"
const x = { a: 1, b: 2, c: 3 }assert.deepStrictEqual( Record.collect(x, (key, n) => [key, n]), [ ["a", 1], ["b", 2], ["c", 3] ])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>}Since v2.0.0
toEntries
Section titled “toEntries”Takes a record and returns an array of tuples containing its keys and values.
Example (Converting a record to entries)
import { Record } from "effect"import * as assert from "node:assert"
const x = { a: 1, b: 2, c: 3 }assert.deepStrictEqual(Record.toEntries(x), [ ["a", 1], ["b", 2], ["c", 3]])Signature
declare const toEntries: <K extends string, A>(self: ReadonlyRecord<K, A>) => Array<[K, A]>Since v2.0.0
elements
Section titled “elements”findFirst
Section titled “findFirst”Returns the first entry that satisfies the specified
predicate, or None if no such entry exists.
Example (Finding the first matching entry)
import { Record } from "effect"
const record = { a: 1, b: 2, c: 3 }const result = Record.findFirst(record, (value, key) => value > 1 && key !== "b")console.log(result) // Option.Some(["c", 3])Signature
declare const findFirst: { <K extends string | symbol, V, V2 extends V>( refinement: (value: NoInfer<V>, key: NoInfer<K>) => value is V2 ): (self: ReadonlyRecord<K, V>) => Option.Option<[K, V2]> <K extends string | symbol, V>( predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean ): (self: ReadonlyRecord<K, V>) => Option.Option<[K, V]> <K extends string | symbol, V, V2 extends V>( self: ReadonlyRecord<K, V>, refinement: (value: NoInfer<V>, key: NoInfer<K>) => value is V2 ): Option.Option<[K, V2]> <K extends string | symbol, V>( self: ReadonlyRecord<K, V>, predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean ): Option.Option<[K, V]>}Since v3.14.0
filtering
Section titled “filtering”filter
Section titled “filter”Selects properties from a record whose values match the given predicate.
Example (Filtering record values)
import { Record } from "effect"import * as assert from "node:assert"
const x = { a: 1, b: 2, c: 3, d: 4 }assert.deepStrictEqual( Record.filter(x, (n) => n > 2), { c: 3, d: 4 })Signature
declare const filter: { <K extends string, A, B extends A>( 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 extends A>( 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>}Since v2.0.0
filterMap
Section titled “filterMap”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.
Example (Filtering and mapping with Result)
import { Record, Result } from "effect"import * as assert from "node:assert"
const x = { a: 1, b: 2, c: 3 }const f = (a: number, key: string) => (a > 2 ? Result.succeed(a * 2) : Result.failVoid)assert.deepStrictEqual(Record.filterMap(x, f), { c: 6 })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>}Since v2.0.0
getFailures
Section titled “getFailures”Returns a new record containing only the Err values from a record of
Result values, preserving the original keys.
Example (Extracting Result failures)
import { Record, Result } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.getFailures({ a: Result.succeed(1), b: Result.fail("err"), c: Result.succeed(2) }), { b: "err" })Signature
declare const getFailures: <K extends string, A, E>( self: ReadonlyRecord<K, Result<A, E>>) => Record<ReadonlyRecord.NonLiteralKey<K>, E>Since v4.0.0
getSomes
Section titled “getSomes”Returns a new record containing only the Some values from a record of
Option values, preserving the original keys.
Example (Extracting Some values)
import { Option, Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.getSomes({ a: Option.some(1), b: Option.none(), c: Option.some(2) }), { a: 1, c: 2 })Signature
declare const getSomes: <K extends string, A>( self: ReadonlyRecord<K, Option.Option<A>>) => Record<ReadonlyRecord.NonLiteralKey<K>, A>Since v2.0.0
getSuccesses
Section titled “getSuccesses”Returns a new record containing only the Ok values from a record of
Result values, preserving the original keys.
Example (Extracting Result successes)
import { Record, Result } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.getSuccesses({ a: Result.succeed(1), b: Result.fail("err"), c: Result.succeed(2) }), { a: 1, c: 2 })Signature
declare const getSuccesses: <K extends string, A, E>(self: ReadonlyRecord<K, Result<A, E>>) => Record<string, A>Since v4.0.0
partition
Section titled “partition”Applies a function to each record entry and partitions the returned Result
values into two records.
Details
Failure values are collected in the left record, and success values are collected in the right record, preserving the original keys.
Example (Partitioning with Result)
import { Record, Result } from "effect"import * as assert from "node:assert"
const x = { a: 1, b: 2, c: 3 }const f = (n: number) => (n % 2 === 0 ? Result.succeed(n) : Result.fail(n))assert.deepStrictEqual(Record.partition(x, f), [{ a: 1, c: 3 }, { b: 2 }])Signature
declare const partition: { <K extends string, A, B, C>( f: (input: A, key: K) => Result<C, B> ): ( self: ReadonlyRecord<K, A> ) => [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>] <K extends string, A, B, C>( self: ReadonlyRecord<K, A>, f: (input: A, key: K) => Result<C, B> ): [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>]}Since v2.0.0
separate
Section titled “separate”Partitions a record of Result values into two separate records,
one with the Err values and one with the Ok values.
Example (Separating Result values)
import { Record, Result } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.separate({ a: Result.fail("e"), b: Result.succeed(1) }), [{ a: "e" }, { b: 1 }])Signature
declare const separate: <K extends string, A, B>( self: ReadonlyRecord<K, Result<B, A>>) => [Record<ReadonlyRecord.NonLiteralKey<K>, A>, Record<ReadonlyRecord.NonLiteralKey<K>, B>]Since v2.0.0
folding
Section titled “folding”reduce
Section titled “reduce”Reduces a record to a single value by combining its entries with a specified function.
Example (Reducing record values)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.reduce({ a: 1, b: 2, c: 3 }, 0, (acc, value, key) => acc + value), 6)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}Since v2.0.0
getters
Section titled “getters”Retrieves a value at a particular key from a record safely, returning it wrapped in an Option.
Example (Getting a value as an Option)
import { Option, Record as R } from "effect"import * as assert from "node:assert"
const person: Record<string, unknown> = { name: "John Doe", age: 35 }
assert.deepStrictEqual(R.get(person, "name"), Option.some("John Doe"))assert.deepStrictEqual(R.get(person, "email"), Option.none())Signature
declare const get: { <K extends string | symbol>(key: NoInfer<K>): <A>(self: ReadonlyRecord<K, A>) => Option.Option<A> <K extends string | symbol, A>(self: ReadonlyRecord<K, A>, key: NoInfer<K>): Option.Option<A>}Since v2.0.0
Retrieves the keys of a given record as an array.
Example (Getting record keys)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.keys({ a: 1, b: 2, c: 3 }), ["a", "b", "c"])Signature
declare const keys: <K extends string | symbol, A>(self: ReadonlyRecord<K, A>) => Array<K & string>Since v2.0.0
Returns the number of key/value pairs in a record.
Example (Getting the record size)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.size({ a: "a", b: 1, c: true }), 3)Signature
declare const size: <K extends string, A>(self: ReadonlyRecord<K, A>) => numberSince v2.0.0
values
Section titled “values”Retrieves the values of a given record as an array.
Example (Getting record values)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.values({ a: 1, b: 2, c: 3 }), [1, 2, 3])Signature
declare const values: <K extends string, A>(self: ReadonlyRecord<K, A>) => Array<A>Since v2.0.0
guards
Section titled “guards”Checks whether a given key exists in a record.
Example (Checking key membership)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.has({ a: 1, b: 2 }, "a"), true)assert.deepStrictEqual(Record.has(Record.empty<string>(), "c"), false)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}Since v2.0.0
isEmptyReadonlyRecord
Section titled “isEmptyReadonlyRecord”Determines if a readonly record is empty.
Example (Checking for an empty readonly record)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.isEmptyReadonlyRecord({}), true)assert.deepStrictEqual(Record.isEmptyReadonlyRecord({ a: 3 }), false)Signature
declare const isEmptyReadonlyRecord: <K extends string, A>( self: ReadonlyRecord<K, A>) => self is ReadonlyRecord<K, never>Since v2.0.0
isEmptyRecord
Section titled “isEmptyRecord”Determines if a mutable record is empty.
Example (Checking for an empty record)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.isEmptyRecord({}), true)assert.deepStrictEqual(Record.isEmptyRecord({ a: 3 }), false)Signature
declare const isEmptyRecord: <K extends string, A>(self: Record<K, A>) => self is Record<K, never>Since v2.0.0
instances
Section titled “instances”makeEquivalence
Section titled “makeEquivalence”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.
Example (Comparing records with a value equivalence)
import { Equal, Record } from "effect"import * as assert from "node:assert"
const recordEquivalence = Record.makeEquivalence(Equal.asEquivalence<number>())
assert.deepStrictEqual(recordEquivalence({ a: 1, b: 2 }, { a: 1, b: 2 }), true)assert.deepStrictEqual(recordEquivalence({ a: 1, b: 2 }, { a: 1, b: 3 }), false)Signature
declare const makeEquivalence: <K extends string, A>(equivalence: Equivalence<A>) => Equivalence<ReadonlyRecord<K, A>>Since v4.0.0
mapping
Section titled “mapping”Maps a record into another record by applying a transformation function to each of its values.
Example (Mapping record values)
import { Record } from "effect"import * as assert from "node:assert"
const f = (n: number) => `-${n}`
assert.deepStrictEqual(Record.map({ a: 3, b: 5 }, f), { a: "-3", b: "-5" })
const g = (n: number, key: string) => `${key.toUpperCase()}-${n}`
assert.deepStrictEqual(Record.map({ a: 3, b: 5 }, g), { a: "A-3", b: "B-5" })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>}Since v2.0.0
mapEntries
Section titled “mapEntries”Maps entries of a ReadonlyRecord using the provided function, allowing modification of both keys and corresponding values.
Example (Mapping record entries)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.mapEntries({ a: 3, b: 5 }, (a, key) => [key.toUpperCase(), a + 1]), { A: 4, B: 6 })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>}Since v2.0.0
mapKeys
Section titled “mapKeys”Maps the keys of a ReadonlyRecord while preserving the corresponding values.
Example (Mapping record keys)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.mapKeys({ a: 3, b: 5 }, (key) => key.toUpperCase()), { A: 3, B: 5 })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>}Since v2.0.0
models
Section titled “models”ReadonlyRecord (type alias)
Section titled “ReadonlyRecord (type alias)”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.
Example (Defining a readonly record type)
import type { Record } from "effect"
// Creating a readonly record typetype UserRecord = Record.ReadonlyRecord<"name" | "age", string | number>
const user: UserRecord = { name: "John", age: 30}Signature
type ReadonlyRecord<K, A> = { readonly [P in K]: A}Since v2.0.0
mutations
Section titled “mutations”modify
Section titled “modify”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.
Example (Modifying a value at a key)
import { 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()Signature
declare const modify: { <K extends string | symbol, A, B>( key: NoInfer<K>, f: (a: A) => B ): (self: ReadonlyRecord<K, A>) => Option.Option<Record<K, A | B>> <K extends string | symbol, A, B>( self: ReadonlyRecord<K, A>, key: NoInfer<K>, f: (a: A) => B ): Option.Option<Record<K, A | B>>}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().
Example (Popping a value and removing its key)
import { 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()Signature
declare const pop: { <K extends string | symbol, X extends K>( key: X ): <A>(self: ReadonlyRecord<K, A>) => Option.Option<[A, Record<Exclude<K, X>, A>]> <K extends string | symbol, A, X extends K>( self: ReadonlyRecord<K, A>, key: X ): Option.Option<[A, Record<Exclude<K, X>, A>]>}Since v2.0.0
remove
Section titled “remove”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.
Example (Removing a key)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.remove({ a: 1, b: 2 }, "a"), { b: 2 })Signature
declare const remove: { <K extends string | symbol, X extends K>(key: X): <A>(self: ReadonlyRecord<K, A>) => Record<Exclude<K, X>, A> <K extends string | symbol, A, X extends K>(self: ReadonlyRecord<K, A>, key: X): Record<Exclude<K, X>, A>}Since v2.0.0
replace
Section titled “replace”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.
Example (Replacing a value at a key)
import { 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()Signature
declare const replace: { <K extends string | symbol, B>( key: NoInfer<K>, b: B ): <A>(self: ReadonlyRecord<K, A>) => Option.Option<Record<K, A | B>> <K extends string | symbol, A, B>(self: ReadonlyRecord<K, A>, key: NoInfer<K>, b: B): Option.Option<Record<K, A | B>>}Since v2.0.0
Adds a new key-value pair or update an existing key’s value in a record.
Example (Setting a record value)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.set("a", 5)({ a: 1, b: 2 }), { a: 5, b: 2 })assert.deepStrictEqual(Record.set("c", 5)({ a: 1, b: 2 }), { a: 1, b: 2, c: 5 })Signature
declare const set: { <K extends string | symbol, K1 extends K | ((string | symbol) & {}), B>( key: K1, value: B ): <A>(self: ReadonlyRecord<K, A>) => Record<K | K1, A | B> <K extends string | symbol, A, K1 extends K | ((string | symbol) & {}), B>( self: ReadonlyRecord<K, A>, key: K1, value: B ): Record<K | K1, A | B>}Since v2.0.0
predicates
Section titled “predicates”Checks whether all entries in a record meet a specific condition.
Example (Checking every record value)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.every({ a: 1, b: 2 }, (n) => n > 0), true)assert.deepStrictEqual( Record.every({ a: 1, b: -1 }, (n) => n > 0), false)Signature
declare const every: { <A, K extends string, B extends A>( 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 extends A>( 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}Since v2.0.0
isSubrecord
Section titled “isSubrecord”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().
Example (Checking subrecords)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual(Record.isSubrecord({ a: 1 } as Record<string, number>, { a: 1, b: 2 }), true)assert.deepStrictEqual(Record.isSubrecord({ a: 1, b: 2 }, { a: 1 } as Record<string, number>), false)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}Since v2.0.0
isSubrecordBy
Section titled “isSubrecordBy”Checks whether all the keys and values in one record are also found in another record. Uses the provided equivalence function to compare values.
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"}
console.log(isSubrecord(required, available)) // trueconsole.log(isSubrecord({ role: "Admin", status: "inactive" }, available)) // falseconsole.log(isSubrecord(required, { role: "editor", status: "active" })) // falseSignature
declare const 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}Since v2.0.0
Checks whether any entry in a record meets a specific condition.
Example (Checking for any matching value)
import { Record } from "effect"import * as assert from "node:assert"
assert.deepStrictEqual( Record.some({ a: 1, b: 2 }, (n) => n > 1), true)assert.deepStrictEqual( Record.some({ a: 1, b: 2 }, (n) => n > 2), false)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}Since v2.0.0
type lambdas
Section titled “type lambdas”ReadonlyRecordTypeLambda (interface)
Section titled “ReadonlyRecordTypeLambda (interface)”Type lambda for readonly records, used in higher-kinded type operations. This enables records to work with generic type constructors and functors.
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}Signature
export interface ReadonlyRecordTypeLambda<K extends string = string> extends TypeLambda { readonly type: ReadonlyRecord<K, this["Target"]>}Since v2.0.0
ReadonlyRecord (namespace)
Section titled “ReadonlyRecord (namespace)”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 typestype GenericKey = Record.ReadonlyRecord.NonLiteralKey<"foo" | "bar"> // string
// Using IntersectKeys to find common keys between record typestype CommonKeys = Record.ReadonlyRecord.IntersectKeys<"a" | "b", "b" | "c"> // "b"Since v2.0.0
NonLiteralKey (type alias)
Section titled “NonLiteralKey (type alias)”Represents a type that converts literal string keys to generic string type and symbol keys to generic symbol type. This is useful for maintaining type safety while allowing flexible key types in record operations.
Example (Converting literal keys to non-literal keys)
import type { Record } from "effect"
// For literal string keys, this becomes 'string'type Example1 = Record.ReadonlyRecord.NonLiteralKey<"foo" | "bar"> // string
// For symbol keys, this becomes 'symbol'type Example2 = Record.ReadonlyRecord.NonLiteralKey<symbol> // symbolSignature
type NonLiteralKey<K> = K extends string ? (IsFiniteString<K> extends true ? string : K) : symbolSince v2.0.0
IntersectKeys (type alias)
Section titled “IntersectKeys (type alias)”Represents the intersection of two key types, handling both literal and non-literal string keys. This type is used in record operations that need to compute overlapping keys.
Example (Intersecting record keys)
import type { Record } from "effect"
// Intersection of literal keystype Example1 = Record.ReadonlyRecord.IntersectKeys<"a" | "b", "b" | "c"> // "b"
// Intersection with generic stringtype Example2 = Record.ReadonlyRecord.IntersectKeys<string, "a" | "b"> // stringSignature
type IntersectKeys<K1, K2> = [string] extends [K1 | K2] ? NonLiteralKey<K1> & NonLiteralKey<K2> : K1 & K2Since v2.0.0