如何为含可选属性的对象创建Eq实例?
解决可选属性对象的Eq实例创建问题
你遇到的问题很典型:可选属性b的类型是string | undefined,但你传入的S.Eq只能处理string类型,所以类型检查报错;同时当前的equals返回false是因为默认的struct Eq会严格比较属性的存在性与值是否都匹配。
简洁解决方案:使用Eq.union组合内置Eq实例
fp-ts已经提供了处理undefined的Eq.eqUndefined,我们可以用Eq.union把它和S.Eq组合成能处理string | undefined的Eq实例:
import * as Eq from 'fp-ts/Eq'; import * as S from 'fp-ts/string'; type Thing = { a: string; b?: string }; // 组合出处理 string | undefined 的 Eq 实例 const eqStringOrUndefined = Eq.union(S.Eq, Eq.eqUndefined); const eqThing = Eq.struct<Thing>({ a: S.Eq, b: eqStringOrUndefined // 类型现在完全匹配 });
测试验证
现在我们验证几个核心场景:
- 两个对象
a相同,一个有b一个无b:返回false(符合预期,属性存在性不同)eqThing.equals({ a: "a", b: "b" }, { a: "a" }); // false - 两个对象
a相同,都没有b属性:返回trueeqThing.equals({ a: "a" }, { a: "a" }); // true - 两个对象
a相同,b属性值相等:返回trueeqThing.equals({ a: "a", b: "b" }, { a: "a", b: "b" }); // true
自定义相等逻辑的备选方案
如果你需要特殊的相等规则(比如认为undefined和空字符串等价),可以用Eq.fromEquals手动实现:
const eqStringOrUndefined = Eq.fromEquals((x, y) => { // 自定义逻辑:将undefined转为空字符串后再比较 const normalizedX = x ?? ""; const normalizedY = y ?? ""; return S.Eq.equals(normalizedX, normalizedY); });
内容的提问来源于stack exchange,提问作者gburnett
相关产品推荐
相关产品推荐

