preserves/implementations/javascript/packages/core/src/is.ts

30 lines
1.1 KiB
TypeScript

import type { GenericEmbedded } from "./embedded";
import type { Annotated } from "./annotated";
export const IsPreservesAnnotated = Symbol.for('IsPreservesAnnotated');
export function isAnnotated<T = GenericEmbedded>(x: any): x is Annotated<T>
{
return !!x?.[IsPreservesAnnotated];
}
export function is(a: any, b: any): boolean {
if (isAnnotated(a)) a = a.item;
if (isAnnotated(b)) b = b.item;
if (Object.is(a, b)) return true;
if (typeof a !== typeof b) return false;
if (typeof a === 'object') {
if (a === null || b === null) return false;
if ('equals' in a && typeof a.equals === 'function') return a.equals(b, is);
if (Array.isArray(a) && Array.isArray(b)) {
const isRecord = 'label' in a;
if (isRecord !== 'label' in b) return false;
if (isRecord && !is((a as any).label, (b as any).label)) return false;
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) if (!is(a[i], b[i])) return false;
return true;
}
}
return false;
}