<A>(value: Equivalence<A>): Equivalence<Record<PropertyKey, A>>Creates an equivalence for objects by comparing all properties using the same equivalence.
When to use
Use when you need to compare records with the same equivalence for every property value.
Details
- Compares all properties present in both objects
- Requires both objects to have the same set of keys; different keys result in
false - All property values must be equivalent according to the provided equivalence
- Supports both string and symbol keys via
Reflect.ownKeys - Empty objects are considered equivalent
- The result is also an equivalence that satisfies reflexive, symmetric, and transitive properties
Example (Defining records with string values)
import { Equivalence } from "effect"
const stringRecordEq = Equivalence.Record(Equivalence.strictEqual<string>())
const record1 = { a: "hello", b: "world" }
const record2 = { a: "hello", b: "world" }
const record3 = { a: "hello", b: "different" }
const record4 = { a: "hello" } // missing key 'b'
console.log(stringRecordEq(record1, record2)) // true
console.log(stringRecordEq(record1, record3)) // false
console.log(stringRecordEq(record1, record4)) // false (different keys)Example (Defining records with number values)
import { Equivalence } from "effect"
const numberRecordEq = Equivalence.Record(Equivalence.strictEqual<number>())
const scores1 = { alice: 100, bob: 85 }
const scores2 = { alice: 100, bob: 85 }
const scores3 = { alice: 100, bob: 90 }
console.log(numberRecordEq(scores1, scores2)) // true
console.log(numberRecordEq(scores1, scores3)) // falseexport function function Record<A>(
value: Equivalence<A>
): Equivalence<Record<PropertyKey, A>>
Creates an equivalence for objects by comparing all properties using the same equivalence.
When to use
Use when you need to compare records with the same equivalence for every
property value.
Details
- Compares all properties present in both objects
- Requires both objects to have the same set of keys; different keys result in
false
- All property values must be equivalent according to the provided equivalence
- Supports both string and symbol keys via
Reflect.ownKeys
- Empty objects are considered equivalent
- The result is also an equivalence that satisfies reflexive, symmetric, and transitive properties
Example (Defining records with string values)
import { Equivalence } from "effect"
const stringRecordEq = Equivalence.Record(Equivalence.strictEqual<string>())
const record1 = { a: "hello", b: "world" }
const record2 = { a: "hello", b: "world" }
const record3 = { a: "hello", b: "different" }
const record4 = { a: "hello" } // missing key 'b'
console.log(stringRecordEq(record1, record2)) // true
console.log(stringRecordEq(record1, record3)) // false
console.log(stringRecordEq(record1, record4)) // false (different keys)
Example (Defining records with number values)
import { Equivalence } from "effect"
const numberRecordEq = Equivalence.Record(Equivalence.strictEqual<number>())
const scores1 = { alice: 100, bob: 85 }
const scores2 = { alice: 100, bob: 85 }
const scores3 = { alice: 100, bob: 90 }
console.log(numberRecordEq(scores1, scores2)) // true
console.log(numberRecordEq(scores1, scores3)) // false
Record<function (type parameter) A in Record<A>(value: Equivalence<A>): Equivalence<Record<PropertyKey, A>>A>(value: Equivalence<A>value: type Equivalence<in A> = (
self: A,
that: A
) => boolean
Represents an equivalence relation over type A.
When to use
Use as a type annotation when you accept or return an equivalence function.
Details
- Returns
boolean: true if values are equivalent, false otherwise
- Must satisfy reflexive, symmetric, and transitive properties
Example (Defining simple number equivalence)
import type { Equivalence } from "effect"
const numberEq: Equivalence.Equivalence<number> = (a, b) => a === b
console.log(numberEq(1, 1)) // true
console.log(numberEq(1, 2)) // false
Example (Defining custom object equivalence)
import type { Equivalence } from "effect"
interface Point {
x: number
y: number
}
const pointEq: Equivalence.Equivalence<Point> = (a, b) =>
a.x === b.x && a.y === b.y
console.log(pointEq({ x: 1, y: 2 }, { x: 1, y: 2 })) // true
Equivalence<function (type parameter) A in Record<A>(value: Equivalence<A>): Equivalence<Record<PropertyKey, A>>A>): type Equivalence<in A> = (
self: A,
that: A
) => boolean
Represents an equivalence relation over type A.
When to use
Use as a type annotation when you accept or return an equivalence function.
Details
- Returns
boolean: true if values are equivalent, false otherwise
- Must satisfy reflexive, symmetric, and transitive properties
Example (Defining simple number equivalence)
import type { Equivalence } from "effect"
const numberEq: Equivalence.Equivalence<number> = (a, b) => a === b
console.log(numberEq(1, 1)) // true
console.log(numberEq(1, 2)) // false
Example (Defining custom object equivalence)
import type { Equivalence } from "effect"
interface Point {
x: number
y: number
}
const pointEq: Equivalence.Equivalence<Point> = (a, b) =>
a.x === b.x && a.y === b.y
console.log(pointEq({ x: 1, y: 2 }, { x: 1, y: 2 })) // true
Equivalence<type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<type PropertyKey =
| string
| number
| symbol
PropertyKey, function (type parameter) A in Record<A>(value: Equivalence<A>): Equivalence<Record<PropertyKey, A>>A>> {
return const make: <A>(
isEquivalent: (self: A, that: A) => boolean
) => Equivalence<A>
Creates a custom equivalence relation with an optimized reference equality check.
When to use
Use when you need an equality rule that the built-in instances and input
mapping helpers cannot express, and you can provide a law-abiding comparison.
Details
The returned equivalence first checks reference equality (===) for
performance. If the values are not the same reference, it falls back to the
provided equivalence function, which must satisfy reflexive, symmetric, and
transitive properties.
Example (Case-insensitive string equivalence)
import { Equivalence } from "effect"
const caseInsensitive = Equivalence.make<string>((a, b) =>
a.toLowerCase() === b.toLowerCase()
)
console.log(caseInsensitive("Hello", "HELLO")) // true
console.log(caseInsensitive("foo", "bar")) // false
// Same reference optimization
const str = "test"
console.log(caseInsensitive(str, str)) // true (fast path)
Example (Comparing numbers with tolerance)
import { Equivalence } from "effect"
const tolerance = Equivalence.make<number>((a, b) => Math.abs(a - b) < 0.0001)
console.log(tolerance(1.0, 1.001)) // false
console.log(tolerance(1.0, 1.00001)) // true
make((self: Record<PropertyKey, A>self, that: Record<PropertyKey, A>that) => {
const const selfKeys: (string | symbol)[]selfKeys = Reflect.function Reflect.ownKeys(target: object): (string | symbol)[]Returns the string and symbol keys of the own properties of an object. The own properties of an object
are those that are defined directly on that object, and are not inherited from the object's prototype.
ownKeys(self: Record<PropertyKey, A>self)
const const thatKeys: (string | symbol)[]thatKeys = Reflect.function Reflect.ownKeys(target: object): (string | symbol)[]Returns the string and symbol keys of the own properties of an object. The own properties of an object
are those that are defined directly on that object, and are not inherited from the object's prototype.
ownKeys(that: Record<PropertyKey, A>that)
if (const selfKeys: (string | symbol)[]selfKeys.Array<T>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.
length !== const thatKeys: (string | symbol)[]thatKeys.Array<T>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.
length) return false
for (const const key: string | symbolkey of const selfKeys: (string | symbol)[]selfKeys) {
if (!var Object: ObjectConstructorProvides functionality common to all JavaScript objects.
Object.ObjectConstructor.hasOwn(o: object, v: PropertyKey): booleanDetermines whether an object has a property with the specified name.
hasOwn(that: Record<PropertyKey, A>that, const key: string | symbolkey) || !value: Equivalence<A>value(self: Record<PropertyKey, A>self[const key: string | symbolkey], that: Record<PropertyKey, A>that[const key: string | symbolkey])) {
return false
}
}
return true
})
}