export const EqualityTraitSymbol = Symbol('Equality') /** * @typedef {{ [EqualityTraitSymbol]:(other:EqualityTrait)=>boolean }} EqualityTrait */ /** * * Utility function to compare any two objects. * * Note that it is expected that the first parameter is more specific than the latter one. * * @example js * class X { [traits.EqualityTraitSymbol] (other) { return other === this } } * class X2 { [traits.EqualityTraitSymbol] (other) { return other === this }, x2 () { return 2 } } * // this is fine * traits.equals(new X2(), new X()) * // this is not, because the left type is less specific than the right one * traits.equals(new X(), new X2()) * * @template {EqualityTrait} T * @param {NoInfer} a * @param {T} b * @return {boolean} */ export const equals = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false