Equivalence
Defines reusable equality functions for values of the same type.
An Equivalence<A> returns true when two A values should be treated as the same for a particular purpose. This module includes strict equality instances for primitive types, constructors for custom comparisons, and helpers for tuples, arrays, structs, records, dates, and values compared through a derived field.
Combinators
Signature
declare function Record<A>(value: Equivalence<A>): Equivalence<Record<PropertyKey, A>>;Creates an equivalence for objects by comparing their properties using provided equivalences.
When to use
Use when you need an Equivalence for objects with known, fixed property names.
Details
Compares only the properties specified in the struct definition; other properties are ignored. String and symbol keys are supported via Reflect.ownKeys. The result returns true only if all specified properties are equivalent according to their equivalences, and it also satisfies reflexive, symmetric, and transitive properties.
See
Signature
declare function Struct<R extends Record<string, Equivalence<any>>>(
fields: R,
): Equivalence<{ [K in string | number | symbol]: [R[K]] extends [Equivalence<A>] ? A : never }>;Creates an equivalence for tuples with heterogeneous element types.
When to use
Use when you need an Equivalence for fixed-length tuples with per-position equivalences.
Details
Tuples must have the same length; different lengths are never equivalent. Each equivalence is applied to the corresponding element position. The result returns true only if all elements are equivalent according to their respective equivalences, and it also satisfies reflexive, symmetric, and transitive properties.
Signature
declare function Tuple<Elements extends readonly Array<Equivalence<any>>>(elements: Elements): Equivalence<{ [I in string | number | symbol]: [Elements[I]] extends [Equivalence<A>] ? A : never }>Combining
Combines two equivalence relations using logical AND.
When to use
Use when you need to combine exactly two equivalences with AND semantics.
Details
Returns true only if both equivalences return true. The comparison short-circuits when the first equivalence returns false. The result is also an equivalence that satisfies reflexive, symmetric, and transitive properties.
See
Signature
declare const combine: {
<A>(that: Equivalence<A>): (self: Equivalence<A>) => Equivalence<A>;
<A>(self: Equivalence<A>, that: Equivalence<A>): Equivalence<A>;
};combineAll
Combines multiple equivalence relations into a single equivalence using logical AND.
When to use
Use when you need to combine many Equivalence instances from an iterable.
Details
Returns true only if all equivalences in the collection return true. The comparison stops at the first equivalence that returns false. Empty collections return an equivalence that always returns true. The result is also an equivalence that satisfies reflexive, symmetric, and transitive properties.
See
Signature
declare function combineAll<A>(collection: Iterable<Equivalence<A>>): Equivalence<A>;Constructors
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.
See
Signature
declare function make<A>(isEquivalent: (self: A, that: A) => boolean): Equivalence<A>;makeReducer
Creates a Reducer for combining Equivalence instances, useful for aggregating equivalences in collections.
When to use
Use when you need a reducer that combines equivalences.
Details
Returns a reducer that combines equivalences using combine. The identity element for empty collections is an equivalence that always returns true. The reducer uses combineAll for collections of equivalences and can be used with fold operations.
See
combineCombine two equivalencescombineAllCombine multiple equivalencesReducerReducer type for collection operations
Signature
declare function makeReducer<A>(): Reducer<Equivalence<A>>;strictEqual
Creates an equivalence relation that uses strict equality (===) to compare values.
When to use
Use when you need strict equality (===) as the comparison.
Details
Uses JavaScript's strict equality operator (===). Primitives compare by value. Objects compare by reference, so only the same object instance is equivalent. Use this as a building block for more complex equivalences via mapInput or combine.
Gotchas
NaN !== NaN, so NaN values are never considered equivalent.
See
makeEqualfor structural equality
Signature
declare const strictEqual: <A>() => Equivalence<A>;Instances
Equivalence instance for bigints using strict equality (===).
When to use
Use when you need to supply bigint equality.
Signature
declare const BigInt: Equivalence<bigint>;Equivalence instance for booleans using strict equality (===).
When to use
Use when you need to supply boolean equality.
Signature
declare const Boolean: Equivalence<boolean>;Equivalence instance for Date objects that compares their getTime() values using Equivalence.Number.
When to use
Use when you need an Equivalence for JavaScript date objects by their millisecond timestamp.
Details
Different Date instances that represent the same millisecond timestamp are equivalent. Because Equivalence.Number treats NaN as equal to NaN, two invalid Date values are also considered equivalent.
See
Numberfor the numeric equivalence applied to eachDate#getTime()resultmapInputfor deriving an equivalence by mapping inputs before comparisonstrictEqualfor reference equality when two values must be the same object
Signature
declare const Date: Equivalence<Date>;Equivalence instance for numbers.
When to use
Use when you need numeric equality that treats NaN as equal to itself.
Signature
declare const Number: Equivalence<number>;Equivalence instance for strings using strict equality (===).
When to use
Use when you need to supply case-sensitive string equality.
Signature
declare const String: Equivalence<string>;Mapping
Transforms an equivalence relation by mapping the input values before comparison.
When to use
Use when you need an equivalence for one type by comparing a derived value.
Details
- Applies the transformation function to both values before comparing - The transformation function should be pure and have no side effects - The resulting equivalence compares the transformed values using the provided equivalence - The result is also an equivalence that satisfies reflexive, symmetric, and transitive properties - Useful for comparing by one property or normalizing values before comparison, such as case-insensitive strings
See
Signature
declare const mapInput: {
<B, A>(f: (b: B) => A): (self: Equivalence<A>) => Equivalence<B>;
<A, B>(self: Equivalence<A>, f: (b: B) => A): Equivalence<B>;
};Models
Equivalence type
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
See
Signature
type Equivalence<in A> = (self: A, that: A) => boolean;Other
Utility Types
EquivalenceTypeLambda interface
Type lambda for Equivalence, used for higher-kinded type operations.
When to use
Use when you need to abstract over Equivalence in higher-kinded type code.
Details
- Enables Equivalence to work with the Effect type system's HKT infrastructure - Used internally for type-level computations and generic abstractions
See
Signature
interface EquivalenceTypeLambda extends TypeLambda {
readonly type: Equivalence<unknown>;
}
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 viaReflect.ownKeys- Empty objects are considered equivalent - The result is also an equivalence that satisfies reflexive, symmetric, and transitive properties