UNPKG

object-deep-compare

Version:

A type-safe collection of comparison methods for objects and arrays in TypeScript/JavaScript

130 lines (129 loc) 4.19 kB
"use strict"; /** * Core utility functions for object comparison */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getTypeName = exports.pick = exports.areValuesEqual = exports.isObject = exports.isEmpty = exports.hasOwn = void 0; /** * Helper function to check if an object has a property * @param obj - Object to check * @param key - Property to check for * @returns Whether the object has the property */ const hasOwn = (obj, key) => { return Object.prototype.hasOwnProperty.call(obj, key); }; exports.hasOwn = hasOwn; /** * Helper function to check if a value is empty * @param value - Value to check * @returns Whether the value is empty */ const isEmpty = (value) => { if (value === null || value === undefined) return true; if (typeof value === 'string') return value.length === 0; if (Array.isArray(value)) return value.length === 0; if (typeof value === 'object') return Object.keys(value).length === 0; return false; }; exports.isEmpty = isEmpty; /** * Helper function to check if a value is an object * @param value - Value to check * @returns Whether the value is an object */ const isObject = (value) => { return typeof value === 'object' && value !== null && !Array.isArray(value); }; exports.isObject = isObject; /** * Helper function to determine if two values are equal * @param a - First value * @param b - Second value * @param strict - Whether to use strict equality * @returns Whether the values are equal */ const areValuesEqual = (a, b, strict = true) => { // Handle identical values first if (a === b) return true; // If strict mode is enabled and values are not strictly equal, they're not equal if (strict) return false; // For non-strict mode: // Handle NaN if (Number.isNaN(a) && Number.isNaN(b)) return true; // Handle null and undefined if ((a === null && b === undefined) || (a === undefined && b === null)) return true; // Handle type coercion for primitives if (typeof a === 'string' || typeof b === 'string') { // Only try numeric comparison if one is a string and the other is a number if ((typeof a === 'string' && typeof b === 'number') || (typeof a === 'number' && typeof b === 'string')) { const numA = Number(a); const numB = Number(b); if (!Number.isNaN(numA) && !Number.isNaN(numB) && numA === numB) return true; } } // Handle boolean values if (typeof a === 'boolean' || typeof b === 'boolean') { const boolA = Boolean(a); const boolB = Boolean(b); if (boolA === boolB) return true; } // At this point, if one is falsy and the other is not, they're not equal if (!a || !b) return false; // If both are dates if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime(); // If both are RegExp if (a instanceof RegExp && b instanceof RegExp) return a.toString() === b.toString(); return false; }; exports.areValuesEqual = areValuesEqual; /** * Creates a filtered copy of an object with only the specified keys * @param obj - Object to filter * @param keys - Keys to include in the result * @returns A new object with only the specified keys */ const pick = (obj, keys) => { return keys.reduce((result, key) => { if ((0, exports.hasOwn)(obj, key)) { result[key] = obj[key]; } return result; }, {}); }; exports.pick = pick; /** * Gets the type name of a value for better type information * @param value - The value to get the type of * @returns A string representing the type */ const getTypeName = (value) => { if (value === null) return 'null'; if (value === undefined) return 'undefined'; if (Array.isArray(value)) return 'array'; if (value instanceof Date) return 'date'; if (value instanceof RegExp) return 'regexp'; if (typeof value === 'object') return 'object'; return typeof value; }; exports.getTypeName = getTypeName;