Equivalence
为 TypeScript 值定义并自定义等价关系。
Equivalence 模块提供了一种在 TypeScript 中定义值之间等价关系的方式。等价关系是一种自反、对称且传递的二元关系,它为“两个值何时应被视为等价”建立了形式化的定义。
什么是 Equivalence?
一个 Equivalence<A> 表示一个函数,它比较两个类型为 A 的值并判断它们是否等价。与使用 === 的简单相等性检查相比,这种方式更灵活、也更可定制。
Equivalence 的结构如下:
interface Equivalence<A> {
(self: A, that: A): boolean
}
使用内置的 Equivalence
该模块为常见数据类型提供了若干内置的等价关系:
| Equivalence | 说明 |
|---|---|
String | 对字符串使用严格相等(===) |
Number | 对数字使用严格相等(===) |
Boolean | 对布尔值使用严格相等(===) |
strictEqual<symbol>() | 对 symbol 使用严格相等(===) |
BigInt | 对 bigint 使用严格相等(===) |
Date | 按时间戳比较 Date 对象 |
示例(使用内置的 Equivalence)
import { Equivalence } from "effect"
console.log(Equivalence.String("apple", "apple"))
Equivalence.String("apple", "apple") // => true
console.log(Equivalence.String("apple", "orange"))
Equivalence.String("apple", "orange") // => false
console.log(Equivalence.Date(new Date(2023, 1, 1), new Date(2023, 1, 1)))
Equivalence.Date(new Date(2023, 1, 1), new Date(2023, 1, 1)) // => true
console.log(Equivalence.Date(new Date(2023, 1, 1), new Date(2023, 10, 1)))
Equivalence.Date(new Date(2023, 1, 1), new Date(2023, 10, 1)) // => false
派生 Equivalence
对于更复杂的数据结构,你可能需要自定义的等价关系。Equivalence 模块允许你通过 Equivalence.mapInput 函数,从已有的 Equivalence 实例派生出新的实例。
示例(为对象创建自定义的 Equivalence)
import { Equivalence } from "effect"
interface User {
readonly id: number
readonly name: string
}
// Create an equivalence that compares User objects based only on the id
const equivalence = Equivalence.mapInput(
Equivalence.Number, // Base equivalence for comparing numbers
(user: User) => user.id, // Function to extract the id from a User
)
// Compare two User objects: they are equivalent if their ids are the same
console.log(equivalence({ id: 1, name: "Alice" }, { id: 1, name: "Al" }))
equivalence({ id: 1, name: "Alice" }, { id: 1, name: "Al" }) // => true
Equivalence.mapInput 函数接收两个参数:
- 你想用作基础的现有
Equivalence(这里是Equivalence.Number,用于比较数字)。 - 一个从你的数据结构中提取值的函数,该值用于等价性检查(这里是
(user: User) => user.id)。