| /** | |
| * 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 2.0.0 | |
| */ | |
| import type * as Combiner from "./Combiner.ts" | |
| import * as Equal from "./Equal.ts" | |
| import type { Equivalence } from "./Equivalence.ts" | |
| import { dual, identity } from "./Function.ts" | |
| import type { TypeLambda } from "./HKT.ts" | |
| import * as Option from "./Option.ts" | |
| import * as Reducer from "./Reducer.ts" | |
| import type { Result } from "./Result.ts" | |
| import * as R from "./Result.ts" | |
| import type { NoInfer } from "./Types.ts" | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 | |
| * } | |
| * ``` | |
| * | |
| * @category models | |
| * @since 2.0.0 | |
| */ | |
| export type ReadonlyRecord<in out K extends string | symbol, out A> = { | |
| readonly [P in K]: A | |
| } | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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" | |
| * ``` | |
| * | |
| * @since 2.0.0 | |
| */ | |
| export declare namespace ReadonlyRecord { | |
| type IsFiniteString<T extends string> = T extends "" ? true : | |
| [T] extends [`${infer Head}${infer Rest}`] | |
| ? string extends Head ? false : `${number}` extends Head ? false : Rest extends "" ? true : IsFiniteString<Rest> | |
| : false | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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> // symbol | |
| * ``` | |
| * | |
| * @category models | |
| * @since 2.0.0 | |
| */ | |
| export type NonLiteralKey<K extends string | symbol> = K extends string ? IsFiniteString<K> extends true ? string : K | |
| : symbol | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * import type { Record } from "effect" | |
| * | |
| * // Intersection of literal keys | |
| * type Example1 = Record.ReadonlyRecord.IntersectKeys<"a" | "b", "b" | "c"> // "b" | |
| * | |
| * // Intersection with generic string | |
| * type Example2 = Record.ReadonlyRecord.IntersectKeys<string, "a" | "b"> // string | |
| * ``` | |
| * | |
| * @category models | |
| * @since 2.0.0 | |
| */ | |
| export type IntersectKeys<K1 extends string, K2 extends string> = [string] extends [K1 | K2] ? | |
| NonLiteralKey<K1> & NonLiteralKey<K2> | |
| : K1 & K2 | |
| } | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 | |
| * } | |
| * ``` | |
| * | |
| * @category type lambdas | |
| * @since 2.0.0 | |
| */ | |
| export interface ReadonlyRecordTypeLambda<K extends string = string> extends TypeLambda { | |
| readonly type: ReadonlyRecord<K, this["Target"]> | |
| } | |
| /** | |
| * Creates a new, empty record. | |
| * | |
| * **Example** (Creating an empty record) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * | |
| * // Create an empty record | |
| * const emptyRecord = Record.empty<string, number>() | |
| * console.log(emptyRecord) // {} | |
| * | |
| * // The type ensures type safety for future operations | |
| * const withValue = Record.set(emptyRecord, "count", 42) | |
| * console.log(withValue) // { count: 42 } | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 2.0.0 | |
| */ | |
| export const empty = <K extends string | symbol = never, V = never>(): Record< | |
| ReadonlyRecord.NonLiteralKey<K>, | |
| V | |
| > => ({} as any) | |
| /** | |
| * Determines if a mutable record is empty. | |
| * | |
| * **Example** (Checking for an empty record) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.isEmptyRecord({}), true) | |
| * assert.deepStrictEqual(Record.isEmptyRecord({ a: 3 }), false) | |
| * ``` | |
| * | |
| * @category guards | |
| * @since 2.0.0 | |
| */ | |
| export const isEmptyRecord = <K extends string, A>(self: Record<K, A>): self is Record<K, never> => | |
| Object.keys(self).length === 0 | |
| /** | |
| * Determines if a readonly record is empty. | |
| * | |
| * **Example** (Checking for an empty readonly record) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.isEmptyReadonlyRecord({}), true) | |
| * assert.deepStrictEqual(Record.isEmptyReadonlyRecord({ a: 3 }), false) | |
| * ``` | |
| * | |
| * @category guards | |
| * @since 2.0.0 | |
| */ | |
| export const isEmptyReadonlyRecord: <K extends string, A>( | |
| self: ReadonlyRecord<K, A> | |
| ) => self is ReadonlyRecord<K, never> = isEmptyRecord | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 2.0.0 | |
| */ | |
| <A, K extends string | symbol, B>(f: (a: A) => readonly [K, B]): (self: Iterable<A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 2.0.0 | |
| */ | |
| <A, K extends string | symbol, B>(self: Iterable<A>, f: (a: A) => readonly [K, B]): Record<ReadonlyRecord.NonLiteralKey<K>, B> | |
| } = dual( | |
| 2, | |
| <A, K extends string, B>( | |
| self: Iterable<A>, | |
| f: (a: A) => readonly [K, B] | |
| ): Record<ReadonlyRecord.NonLiteralKey<K>, B> => { | |
| const out: Record<string, B> = empty() | |
| for (const a of self) { | |
| const [k, b] = f(a) | |
| out[k] = b | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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" } | |
| * } | |
| * ) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 2.0.0 | |
| */ | |
| export const fromIterableBy = <A, K extends string | symbol>( | |
| items: Iterable<A>, | |
| f: (a: A) => K | |
| ): Record<ReadonlyRecord.NonLiteralKey<K>, A> => fromIterableWith(items, (a) => [f(a), a]) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 2.0.0 | |
| */ | |
| export const fromEntries: <Entry extends readonly [string | symbol, any]>( | |
| entries: Iterable<Entry> | |
| ) => Record<ReadonlyRecord.NonLiteralKey<Entry[0]>, Entry[1]> = Object.fromEntries | |
| /** | |
| * Transforms the values of a record into an `Array` with a custom mapping function. | |
| * | |
| * **Example** (Collecting mapped record values) | |
| * | |
| * ```ts | |
| * 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]]) | |
| * ``` | |
| * | |
| * @category converting | |
| * @since 2.0.0 | |
| */ | |
| export const collect: { | |
| /** | |
| * Transforms the values of a record into an `Array` with a custom mapping function. | |
| * | |
| * **Example** (Collecting mapped record values) | |
| * | |
| * ```ts | |
| * 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]]) | |
| * ``` | |
| * | |
| * @category converting | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, B>(f: (key: K, a: A) => B): (self: ReadonlyRecord<K, A>) => Array<B> | |
| /** | |
| * Transforms the values of a record into an `Array` with a custom mapping function. | |
| * | |
| * **Example** (Collecting mapped record values) | |
| * | |
| * ```ts | |
| * 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]]) | |
| * ``` | |
| * | |
| * @category converting | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, B>(self: ReadonlyRecord<K, A>, f: (key: K, a: A) => B): Array<B> | |
| } = dual( | |
| 2, | |
| <K extends string, A, B>(self: ReadonlyRecord<K, A>, f: (key: K, a: A) => B): Array<B> => { | |
| const out: Array<B> = [] | |
| for (const key of keys(self)) { | |
| out.push(f(key, self[key])) | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * Takes a record and returns an array of tuples containing its keys and values. | |
| * | |
| * **Example** (Converting a record to entries) | |
| * | |
| * ```ts | |
| * 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]]) | |
| * ``` | |
| * | |
| * @category converting | |
| * @since 2.0.0 | |
| */ | |
| export const toEntries: <K extends string, A>(self: ReadonlyRecord<K, A>) => Array<[K, A]> = collect(( | |
| key, | |
| value | |
| ) => [key, value]) | |
| /** | |
| * Returns the number of key/value pairs in a record. | |
| * | |
| * **Example** (Getting the record size) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.size({ a: "a", b: 1, c: true }), 3) | |
| * ``` | |
| * | |
| * @category getters | |
| * @since 2.0.0 | |
| */ | |
| export const size = <K extends string, A>(self: ReadonlyRecord<K, A>): number => keys(self).length | |
| /** | |
| * Checks whether a given `key` exists in a record. | |
| * | |
| * **Example** (Checking key membership) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category guards | |
| * @since 2.0.0 | |
| */ | |
| export const has: { | |
| /** | |
| * Checks whether a given `key` exists in a record. | |
| * | |
| * **Example** (Checking key membership) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category guards | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol>(key: NoInfer<K>): <A>(self: ReadonlyRecord<K, A>) => boolean | |
| /** | |
| * Checks whether a given `key` exists in a record. | |
| * | |
| * **Example** (Checking key membership) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category guards | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A>(self: ReadonlyRecord<K, A>, key: NoInfer<K>): boolean | |
| } = dual( | |
| 2, | |
| <K extends string | symbol, A>( | |
| self: ReadonlyRecord<K, A>, | |
| key: NoInfer<K> | |
| ): boolean => Object.hasOwn(self, key) | |
| ) | |
| /** | |
| * Retrieves a value at a particular key from a record safely, returning it wrapped in an `Option`. | |
| * | |
| * **Example** (Getting a value as an Option) | |
| * | |
| * ```ts | |
| * 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()) | |
| * ``` | |
| * | |
| * @category getters | |
| * @since 2.0.0 | |
| */ | |
| export const get: { | |
| /** | |
| * Retrieves a value at a particular key from a record safely, returning it wrapped in an `Option`. | |
| * | |
| * **Example** (Getting a value as an Option) | |
| * | |
| * ```ts | |
| * 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()) | |
| * ``` | |
| * | |
| * @category getters | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol>(key: NoInfer<K>): <A>(self: ReadonlyRecord<K, A>) => Option.Option<A> | |
| /** | |
| * Retrieves a value at a particular key from a record safely, returning it wrapped in an `Option`. | |
| * | |
| * **Example** (Getting a value as an Option) | |
| * | |
| * ```ts | |
| * 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()) | |
| * ``` | |
| * | |
| * @category getters | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A>(self: ReadonlyRecord<K, A>, key: NoInfer<K>): Option.Option<A> | |
| } = dual( | |
| 2, | |
| <K extends string | symbol, A>(self: ReadonlyRecord<K, A>, key: NoInfer<K>): Option.Option<A> => | |
| has(self, key) ? Option.some(self[key]) : Option.none() | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A, B>(key: NoInfer<K>, f: (a: A) => B): (self: ReadonlyRecord<K, A>) => Option.Option<Record<K, A | B>> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A, B>(self: ReadonlyRecord<K, A>, key: NoInfer<K>, f: (a: A) => B): Option.Option<Record<K, A | B>> | |
| } = dual( | |
| 3, | |
| <K extends string | symbol, A, B>( | |
| self: ReadonlyRecord<K, A>, | |
| key: NoInfer<K>, | |
| f: (a: A) => B | |
| ): Option.Option<Record<K, A | B>> => { | |
| if (!has(self, key)) return Option.none() | |
| return Option.some({ ...self, [key]: f(self[key]) }) | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, B>(key: NoInfer<K>, b: B): <A>(self: ReadonlyRecord<K, A>) => Option.Option<Record<K, A | B>> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A, B>(self: ReadonlyRecord<K, A>, key: NoInfer<K>, b: B): Option.Option<Record<K, A | B>> | |
| } = dual( | |
| 3, | |
| <K extends string | symbol, A, B>( | |
| self: ReadonlyRecord<K, A>, | |
| key: NoInfer<K>, | |
| b: B | |
| ): Option.Option<Record<K, A | B>> => modify(self, key, () => b) | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.remove({ a: 1, b: 2 }, "a"), { b: 2 }) | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.remove({ a: 1, b: 2 }, "a"), { b: 2 }) | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, X extends K>(key: X): <A>(self: ReadonlyRecord<K, A>) => Record<Exclude<K, X>, A> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.remove({ a: 1, b: 2 }, "a"), { b: 2 }) | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A, X extends K>(self: ReadonlyRecord<K, A>, key: X): Record<Exclude<K, X>, A> | |
| } = dual( | |
| 2, | |
| <K extends string | symbol, A, X extends K>(self: ReadonlyRecord<K, A>, key: X): Record<Exclude<K, X>, A> => { | |
| if (!has(self, key)) { | |
| return { ...self } | |
| } | |
| const out = { ...self } | |
| delete out[key] | |
| return out | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| export const pop: { | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, X extends K>(key: X): <A>(self: ReadonlyRecord<K, A>) => Option.Option<[A, Record<Exclude<K, X>, A>]> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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() | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A, X extends K>(self: ReadonlyRecord<K, A>, key: X): Option.Option<[A, Record<Exclude<K, X>, A>]> | |
| } = dual(2, <K extends string | symbol, A, X extends K>( | |
| self: ReadonlyRecord<K, A>, | |
| key: X | |
| ): Option.Option<[A, Record<Exclude<K, X>, A>]> => | |
| has(self, key) ? Option.some([self[key], remove(self, key)]) : Option.none()) | |
| /** | |
| * Maps a record into another record by applying a transformation function to each of its values. | |
| * | |
| * **Example** (Mapping record values) | |
| * | |
| * ```ts | |
| * 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" }) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| export const map: { | |
| /** | |
| * Maps a record into another record by applying a transformation function to each of its values. | |
| * | |
| * **Example** (Mapping record values) | |
| * | |
| * ```ts | |
| * 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" }) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, B>(f: (a: A, key: NoInfer<K>) => B): (self: ReadonlyRecord<K, A>) => Record<K, B> | |
| /** | |
| * Maps a record into another record by applying a transformation function to each of its values. | |
| * | |
| * **Example** (Mapping record values) | |
| * | |
| * ```ts | |
| * 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" }) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, B>(self: ReadonlyRecord<K, A>, f: (a: A, key: NoInfer<K>) => B): Record<K, B> | |
| } = dual( | |
| 2, | |
| <K extends string, A, B>(self: ReadonlyRecord<K, A>, f: (a: A, key: NoInfer<K>) => B): Record<K, B> => { | |
| const out: Record<K, B> = { ...self } as any | |
| for (const key of keys(self)) { | |
| out[key] = f(self[key], key) | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * Maps the keys of a `ReadonlyRecord` while preserving the corresponding values. | |
| * | |
| * **Example** (Mapping record keys) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| export const mapKeys: { | |
| /** | |
| * Maps the keys of a `ReadonlyRecord` while preserving the corresponding values. | |
| * | |
| * **Example** (Mapping record keys) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, K2 extends string>(f: (key: K, a: A) => K2): (self: ReadonlyRecord<K, A>) => Record<K2, A> | |
| /** | |
| * Maps the keys of a `ReadonlyRecord` while preserving the corresponding values. | |
| * | |
| * **Example** (Mapping record keys) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, K2 extends string>(self: ReadonlyRecord<K, A>, f: (key: K, a: A) => K2): Record<K2, A> | |
| } = dual( | |
| 2, | |
| <K extends string, A, K2 extends string>( | |
| self: ReadonlyRecord<K, A>, | |
| f: (key: K, a: A) => K2 | |
| ): Record<K2, A> => { | |
| const out: Record<K2, A> = {} as any | |
| for (const key of keys(self)) { | |
| const a = self[key] | |
| out[f(key, a)] = a | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * Maps entries of a `ReadonlyRecord` using the provided function, allowing modification of both keys and corresponding values. | |
| * | |
| * **Example** (Mapping record entries) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| export const mapEntries: { | |
| /** | |
| * Maps entries of a `ReadonlyRecord` using the provided function, allowing modification of both keys and corresponding values. | |
| * | |
| * **Example** (Mapping record entries) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, K2 extends string, B>(f: (a: A, key: K) => readonly [K2, B]): (self: ReadonlyRecord<K, A>) => Record<K2, B> | |
| /** | |
| * Maps entries of a `ReadonlyRecord` using the provided function, allowing modification of both keys and corresponding values. | |
| * | |
| * **Example** (Mapping record entries) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category mapping | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, K2 extends string, B>(self: ReadonlyRecord<K, A>, f: (a: A, key: K) => [K2, B]): Record<K2, B> | |
| } = dual( | |
| 2, | |
| <K extends string, A, K2 extends string, B>( | |
| self: ReadonlyRecord<K, A>, | |
| f: (a: A, key: K) => [K2, B] | |
| ): Record<K2, B> => { | |
| const out = {} as Record<K2, B> | |
| for (const key of keys(self)) { | |
| const [k, b] = f(self[key], key) | |
| out[k] = b | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, B, X>(f: (input: A, key: K) => Result<B, X>): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, B, X>(self: ReadonlyRecord<K, A>, f: (input: A, key: K) => Result<B, X>): Record<ReadonlyRecord.NonLiteralKey<K>, B> | |
| } = dual( | |
| 2, | |
| <K extends string, A, B, X>( | |
| self: ReadonlyRecord<K, A>, | |
| f: (input: A, key: K) => Result<B, X> | |
| ): Record<ReadonlyRecord.NonLiteralKey<K>, B> => { | |
| const out: Record<string, B> = empty() | |
| for (const key of keys(self)) { | |
| const result = f(self[key], key) | |
| if (R.isSuccess(result)) { | |
| out[key] = result.success | |
| } | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * Selects properties from a record whose values match the given predicate. | |
| * | |
| * **Example** (Filtering record values) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| export const filter: { | |
| /** | |
| * Selects properties from a record whose values match the given predicate. | |
| * | |
| * **Example** (Filtering record values) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <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> | |
| /** | |
| * Selects properties from a record whose values match the given predicate. | |
| * | |
| * **Example** (Filtering record values) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A>(predicate: (A: NoInfer<A>, key: K) => boolean): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, A> | |
| /** | |
| * Selects properties from a record whose values match the given predicate. | |
| * | |
| * **Example** (Filtering record values) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A, B extends A>(self: ReadonlyRecord<K, A>, refinement: (a: A, key: K) => a is B): Record<ReadonlyRecord.NonLiteralKey<K>, B> | |
| /** | |
| * Selects properties from a record whose values match the given predicate. | |
| * | |
| * **Example** (Filtering record values) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (a: A, key: K) => boolean): Record<ReadonlyRecord.NonLiteralKey<K>, A> | |
| } = dual( | |
| 2, | |
| <K extends string, A>( | |
| self: ReadonlyRecord<K, A>, | |
| predicate: (a: A, key: K) => boolean | |
| ): Record<ReadonlyRecord.NonLiteralKey<K>, A> => { | |
| const out: Record<string, A> = empty() | |
| for (const key of keys(self)) { | |
| if (predicate(self[key], key)) { | |
| out[key] = self[key] | |
| } | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * Returns a new record containing only the `Some` values from a record of | |
| * `Option` values, preserving the original keys. | |
| * | |
| * **Example** (Extracting Some values) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| export const getSomes: <K extends string, A>( | |
| self: ReadonlyRecord<K, Option.Option<A>> | |
| ) => Record<ReadonlyRecord.NonLiteralKey<K>, A> = <K extends string, A>( | |
| self: ReadonlyRecord<K, Option.Option<A>> | |
| ): Record<ReadonlyRecord.NonLiteralKey<K>, A> => { | |
| const out: Record<string, A> = empty() | |
| for (const key of keys(self)) { | |
| const option = self[key] | |
| if (Option.isSome(option)) { | |
| out[key] = option.value | |
| } | |
| } | |
| return out | |
| } | |
| /** | |
| * Returns a new record containing only the `Err` values from a record of | |
| * `Result` values, preserving the original keys. | |
| * | |
| * **Example** (Extracting Result failures) | |
| * | |
| * ```ts | |
| * 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" } | |
| * ) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 4.0.0 | |
| */ | |
| export const getFailures = <K extends string, A, E>( | |
| self: ReadonlyRecord<K, Result<A, E>> | |
| ): Record<ReadonlyRecord.NonLiteralKey<K>, E> => { | |
| const out: Record<string, E> = empty() | |
| for (const key of keys(self)) { | |
| const value = self[key] | |
| if (R.isFailure(value)) { | |
| out[key] = value.failure | |
| } | |
| } | |
| return out | |
| } | |
| /** | |
| * Returns a new record containing only the `Ok` values from a record of | |
| * `Result` values, preserving the original keys. | |
| * | |
| * **Example** (Extracting Result successes) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 4.0.0 | |
| */ | |
| export const getSuccesses = <K extends string, A, E>( | |
| self: ReadonlyRecord<K, Result<A, E>> | |
| ): Record<string, A> => { | |
| const out: Record<string, A> = empty() | |
| for (const key of keys(self)) { | |
| const value = self[key] | |
| if (R.isSuccess(value)) { | |
| out[key] = value.success | |
| } | |
| } | |
| return out | |
| } | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 }]) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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 }]) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <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>] | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 }]) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| <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>] | |
| } = dual( | |
| 2, | |
| <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>] => { | |
| const left: Record<string, B> = empty() | |
| const right: Record<string, C> = empty() | |
| for (const key of keys(self)) { | |
| const e = f(self[key], key) | |
| if (R.isFailure(e)) { | |
| left[key] = e.failure | |
| } else { | |
| right[key] = e.success | |
| } | |
| } | |
| return [left, right] | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 }] | |
| * ) | |
| * ``` | |
| * | |
| * @category filtering | |
| * @since 2.0.0 | |
| */ | |
| export const separate: <K extends string, A, B>( | |
| self: ReadonlyRecord<K, Result<B, A>> | |
| ) => [Record<ReadonlyRecord.NonLiteralKey<K>, A>, Record<ReadonlyRecord.NonLiteralKey<K>, B>] = partition(identity) | |
| /** | |
| * Retrieves the keys of a given record as an array. | |
| * | |
| * **Example** (Getting record keys) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.keys({ a: 1, b: 2, c: 3 }), ["a", "b", "c"]) | |
| * ``` | |
| * | |
| * @category getters | |
| * @since 2.0.0 | |
| */ | |
| export const keys = <K extends string | symbol, A>(self: ReadonlyRecord<K, A>): Array<K & string> => | |
| Object.keys(self) as Array<K & string> | |
| /** | |
| * Retrieves the values of a given record as an array. | |
| * | |
| * **Example** (Getting record values) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.values({ a: 1, b: 2, c: 3 }), [1, 2, 3]) | |
| * ``` | |
| * | |
| * @category getters | |
| * @since 2.0.0 | |
| */ | |
| export const values = <K extends string, A>(self: ReadonlyRecord<K, A>): Array<A> => collect(self, (_, a) => a) | |
| /** | |
| * Adds a new key-value pair or update an existing key's value in a record. | |
| * | |
| * **Example** (Setting a record value) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| export const set: { | |
| /** | |
| * Adds a new key-value pair or update an existing key's value in a record. | |
| * | |
| * **Example** (Setting a record value) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, K1 extends K | ((string | symbol) & {}), B>(key: K1, value: B): <A>(self: ReadonlyRecord<K, A>) => Record<K | K1, A | B> | |
| /** | |
| * Adds a new key-value pair or update an existing key's value in a record. | |
| * | |
| * **Example** (Setting a record value) | |
| * | |
| * ```ts | |
| * 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 }) | |
| * ``` | |
| * | |
| * @category mutations | |
| * @since 2.0.0 | |
| */ | |
| <K extends string | symbol, A, K1 extends K | ((string | symbol) & {}), B>(self: ReadonlyRecord<K, A>, key: K1, value: B): Record<K | K1, A | B> | |
| } = dual( | |
| 3, | |
| <K extends string | symbol, A, K1 extends K | ((string | symbol) & {}), B>( | |
| self: ReadonlyRecord<K, A>, | |
| key: K1, | |
| value: B | |
| ): Record<K | K1, A | B> => { | |
| return { ...self, [key]: value } as any | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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) | |
| * ) // true | |
| * console.log( | |
| * isSubrecord({ role: "Admin", status: "inactive" }, available) | |
| * ) // false | |
| * console.log( | |
| * isSubrecord(required, { role: "editor", status: "active" }) | |
| * ) // false | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| export 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 | |
| } => | |
| dual(2, <K extends string>(self: ReadonlyRecord<K, A>, that: ReadonlyRecord<K, A>): boolean => { | |
| for (const key of keys(self)) { | |
| if (!has(that, key) || !equivalence(self[key], that[key])) { | |
| return false | |
| } | |
| } | |
| return true | |
| }) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 | |
| * ) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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 | |
| * ) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A>(that: ReadonlyRecord<K, A>): (self: ReadonlyRecord<K, A>) => boolean | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 | |
| * ) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A>(self: ReadonlyRecord<K, A>, that: ReadonlyRecord<K, A>): boolean | |
| } = isSubrecordBy(Equal.asEquivalence()) | |
| /** | |
| * Reduces a record to a single value by combining its entries with a specified function. | |
| * | |
| * **Example** (Reducing record values) | |
| * | |
| * ```ts | |
| * 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 | |
| * ) | |
| * ``` | |
| * | |
| * @category folding | |
| * @since 2.0.0 | |
| */ | |
| export const reduce: { | |
| /** | |
| * Reduces a record to a single value by combining its entries with a specified function. | |
| * | |
| * **Example** (Reducing record values) | |
| * | |
| * ```ts | |
| * 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 | |
| * ) | |
| * ``` | |
| * | |
| * @category folding | |
| * @since 2.0.0 | |
| */ | |
| <Z, V, K extends string>(zero: Z, f: (accumulator: Z, value: V, key: K) => Z): (self: ReadonlyRecord<K, V>) => Z | |
| /** | |
| * Reduces a record to a single value by combining its entries with a specified function. | |
| * | |
| * **Example** (Reducing record values) | |
| * | |
| * ```ts | |
| * 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 | |
| * ) | |
| * ``` | |
| * | |
| * @category folding | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, V, Z>( | |
| self: ReadonlyRecord<K, V>, | |
| zero: Z, | |
| f: (accumulator: Z, value: V, key: K) => Z | |
| ): Z | |
| } = dual( | |
| 3, | |
| <K extends string, V, Z>( | |
| self: ReadonlyRecord<K, V>, | |
| zero: Z, | |
| f: (accumulator: Z, value: V, key: K) => Z | |
| ): Z => { | |
| let out: Z = zero | |
| for (const key of keys(self)) { | |
| out = f(out, self[key], key) | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * Checks whether all entries in a record meet a specific condition. | |
| * | |
| * **Example** (Checking every record value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| export const every: { | |
| /** | |
| * Checks whether all entries in a record meet a specific condition. | |
| * | |
| * **Example** (Checking every record value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <A, K extends string, B extends A>(refinement: (value: A, key: K) => value is B): (self: ReadonlyRecord<K, A>) => self is ReadonlyRecord<K, B> | |
| /** | |
| * Checks whether all entries in a record meet a specific condition. | |
| * | |
| * **Example** (Checking every record value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <A, K extends string>(predicate: (value: A, key: K) => boolean): (self: ReadonlyRecord<K, A>) => boolean | |
| /** | |
| * Checks whether all entries in a record meet a specific condition. | |
| * | |
| * **Example** (Checking every record value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <A, K extends string, B extends A>(self: ReadonlyRecord<K, A>, refinement: (value: A, key: K) => value is B): self is ReadonlyRecord<K, B> | |
| /** | |
| * Checks whether all entries in a record meet a specific condition. | |
| * | |
| * **Example** (Checking every record value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (value: A, key: K) => boolean): boolean | |
| } = dual( | |
| 2, | |
| <A, K extends string, B extends A>( | |
| self: ReadonlyRecord<K, A>, | |
| refinement: (value: A, key: K) => value is B | |
| ): self is ReadonlyRecord<K, B> => { | |
| for (const key of keys(self)) { | |
| if (!refinement(self[key], key)) { | |
| return false | |
| } | |
| } | |
| return true | |
| } | |
| ) | |
| /** | |
| * Checks whether any entry in a record meets a specific condition. | |
| * | |
| * **Example** (Checking for any matching value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| export const some: { | |
| /** | |
| * Checks whether any entry in a record meets a specific condition. | |
| * | |
| * **Example** (Checking for any matching value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <A, K extends string>(predicate: (value: A, key: K) => boolean): (self: ReadonlyRecord<K, A>) => boolean | |
| /** | |
| * Checks whether any entry in a record meets a specific condition. | |
| * | |
| * **Example** (Checking for any matching value) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category predicates | |
| * @since 2.0.0 | |
| */ | |
| <K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (value: A, key: K) => boolean): boolean | |
| } = dual( | |
| 2, | |
| <K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (value: A, key: K) => boolean): boolean => { | |
| for (const key of keys(self)) { | |
| if (predicate(self[key], key)) { | |
| return true | |
| } | |
| } | |
| return false | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| export const union: { | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| <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> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| <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> | |
| } = dual( | |
| 3, | |
| <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> => { | |
| if (isEmptyRecord(self)) { | |
| return { ...that } as any | |
| } | |
| if (isEmptyRecord(that)) { | |
| return { ...self } as any | |
| } | |
| const out: Record<string, A | B | C> = empty() | |
| for (const key of keys(self)) { | |
| if (has(that, key as any)) { | |
| out[key] = combine(self[key], that[key as unknown as K1]) | |
| } else { | |
| out[key] = self[key] | |
| } | |
| } | |
| for (const key of keys(that)) { | |
| if (!has(out, key)) { | |
| out[key] = that[key] | |
| } | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| <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> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| <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> | |
| } = dual( | |
| 3, | |
| <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> => { | |
| const out: Record<string, C> = empty() | |
| if (isEmptyRecord(self) || isEmptyRecord(that)) { | |
| return out | |
| } | |
| for (const key of keys(self)) { | |
| if (has(that, key as any)) { | |
| out[key] = combine(self[key], that[key as unknown as K1]) | |
| } | |
| } | |
| return out | |
| } | |
| ) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| export const 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| <K1 extends string, B>(that: ReadonlyRecord<K1, B>): <K0 extends string, A>(self: ReadonlyRecord<K0, A>) => Record<K0 | K1, A | B> | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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 } | |
| * ) | |
| * ``` | |
| * | |
| * @category combining | |
| * @since 2.0.0 | |
| */ | |
| <K0 extends string, A, K1 extends string, B>(self: ReadonlyRecord<K0, A>, that: ReadonlyRecord<K1, B>): Record<K0 | K1, A | B> | |
| } = dual(2, <K0 extends string, A, K1 extends string, B>( | |
| self: ReadonlyRecord<K0, A>, | |
| that: ReadonlyRecord<K1, B> | |
| ): Record<K0 | K1, A | B> => { | |
| if (isEmptyRecord(self)) { | |
| return { ...that } as any | |
| } | |
| if (isEmptyRecord(that)) { | |
| return { ...self } as any | |
| } | |
| const out = {} as Record<K0 | K1, A | B> | |
| for (const key of keys(self)) { | |
| if (!has(that, key as any)) { | |
| out[key] = self[key] | |
| } | |
| } | |
| for (const key of keys(that)) { | |
| if (!has(self, key as any)) { | |
| out[key] = that[key] | |
| } | |
| } | |
| return out | |
| }) | |
| /** | |
| * 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) | |
| * | |
| * ```ts | |
| * 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) | |
| * ``` | |
| * | |
| * @category instances | |
| * @since 4.0.0 | |
| */ | |
| export const makeEquivalence = <K extends string, A>( | |
| equivalence: Equivalence<A> | |
| ): Equivalence<ReadonlyRecord<K, A>> => { | |
| const is = isSubrecordBy(equivalence) | |
| return (self, that) => is(self, that) && is(that, self) | |
| } | |
| /** | |
| * Create a non-empty record from a single element. | |
| * | |
| * **Example** (Creating a singleton record) | |
| * | |
| * ```ts | |
| * import { Record } from "effect" | |
| * import * as assert from "node:assert" | |
| * | |
| * assert.deepStrictEqual(Record.singleton("a", 1), { a: 1 }) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 2.0.0 | |
| */ | |
| export const singleton = <K extends string | symbol, A>(key: K, value: A): Record<K, A> => ({ | |
| [key]: value | |
| } as any) | |
| /** | |
| * Creates a `Reducer` for combining `Record`s 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 {@link union} for one-off record merging with the same union semantics | |
| * @see {@link makeReducerIntersection} for a reducer that keeps only keys present on both sides | |
| * | |
| * @category combining | |
| * @since 4.0.0 | |
| */ | |
| export function makeReducerUnion<K extends string, A>(combiner: Combiner.Combiner<A>): Reducer.Reducer<Record<K, A>> { | |
| return Reducer.make<Record<K, A>>( | |
| (self, that) => union(self, that, combiner.combine), | |
| {} as Record<K, A> | |
| ) | |
| } | |
| /** | |
| * 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 {@link makeReducerUnion} for a reducer that preserves keys from either input record | |
| * @see {@link intersection} for applying the shared-key merge to one pair of records | |
| * | |
| * @category combining | |
| * @since 4.0.0 | |
| */ | |
| export function makeReducerIntersection<K extends string, A>( | |
| combiner: Combiner.Combiner<A> | |
| ): Reducer.Reducer<Record<K, A>> { | |
| return Reducer.make( | |
| (self, that) => intersection(self, that, combiner.combine) as any, | |
| {} as Record<K, A> | |
| ) | |
| } | |
| /** | |
| * Returns the first entry that satisfies the specified | |
| * predicate, or `None` if no such entry exists. | |
| * | |
| * **Example** (Finding the first matching entry) | |
| * | |
| * ```ts | |
| * 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]) | |
| * ``` | |
| * | |
| * @category elements | |
| * @since 3.14.0 | |
| */ | |
| export const findFirst: { | |
| /** | |
| * Returns the first entry that satisfies the specified | |
| * predicate, or `None` if no such entry exists. | |
| * | |
| * **Example** (Finding the first matching entry) | |
| * | |
| * ```ts | |
| * 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]) | |
| * ``` | |
| * | |
| * @category elements | |
| * @since 3.14.0 | |
| */ | |
| <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]> | |
| /** | |
| * Returns the first entry that satisfies the specified | |
| * predicate, or `None` if no such entry exists. | |
| * | |
| * **Example** (Finding the first matching entry) | |
| * | |
| * ```ts | |
| * 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]) | |
| * ``` | |
| * | |
| * @category elements | |
| * @since 3.14.0 | |
| */ | |
| <K extends string | symbol, V>(predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean): (self: ReadonlyRecord<K, V>) => Option.Option<[K, V]> | |
| /** | |
| * Returns the first entry that satisfies the specified | |
| * predicate, or `None` if no such entry exists. | |
| * | |
| * **Example** (Finding the first matching entry) | |
| * | |
| * ```ts | |
| * 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]) | |
| * ``` | |
| * | |
| * @category elements | |
| * @since 3.14.0 | |
| */ | |
| <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]> | |
| /** | |
| * Returns the first entry that satisfies the specified | |
| * predicate, or `None` if no such entry exists. | |
| * | |
| * **Example** (Finding the first matching entry) | |
| * | |
| * ```ts | |
| * 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]) | |
| * ``` | |
| * | |
| * @category elements | |
| * @since 3.14.0 | |
| */ | |
| <K extends string | symbol, V>( | |
| self: ReadonlyRecord<K, V>, | |
| predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean | |
| ): Option.Option<[K, V]> | |
| } = dual( | |
| 2, | |
| <K extends string | symbol, V>( | |
| self: ReadonlyRecord<K, V>, | |
| f: (value: V, key: K) => boolean | |
| ): Option.Option<[K, V]> => { | |
| const k = keys(self) | |
| for (let i = 0; i < k.length; i++) { | |
| const key = k[i] | |
| if (f(self[key], key)) { | |
| return Option.some([key, self[key]]) | |
| } | |
| } | |
| return Option.none() | |
| } | |
| ) | |
Xet Storage Details
- Size:
- 70.6 kB
- Xet hash:
- 95a6f98c59902374cf61f08a8bb5315d1e502794f5f14722820d0bfa5efaa236
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.