object-deep-compare
A type-safe collection of comparison methods for objects and arrays in TypeScript/JavaScript. This library provides powerful tools for deep comparison of complex data structures with configurable options.
Features
- Type-safe: Written in TypeScript with full type definitions
- Zero dependencies: No external dependencies required
- Flexible equality: Choose between strict and loose equality with the
strict
option - Special value support: Correctly handles comparison of special values like
NaN
,null
, andundefined
- Date object support: Properly compares Date objects based on their time values
- RegExp support: Correctly compares RegExp objects
- Circular reference detection: Can detect and handle circular references in objects and arrays
- Path filtering: Ability to include or exclude specific properties from comparison using wildcard patterns
- Schema validation: Validate objects against expected schemas before comparison
- Performance optimized: Efficient algorithms to minimize processing time
- Configurable: Control comparison behavior through options
- Detailed difference reporting: Get detailed information about each difference including type and actual values
Installation
Using npm:
npm install object-deep-compare
Using yarn:
yarn add object-deep-compare
Usage
CommonJS
const {
CompareProperties,
CompareArrays,
CompareValuesWithConflicts,
CompareValuesWithDetailedDifferences,
// Other functions as needed...
} = require('object-deep-compare');
ES Modules
import {
CompareProperties,
CompareArrays,
CompareValuesWithConflicts,
CompareValuesWithDetailedDifferences,
TypeSafeCompareObjects,
ObjectsAreEqual,
IsSubset,
// Schema validation
ValidateObjectsAgainstSchemas,
// Types
ComparisonOptions,
CircularReferenceHandling,
PathFilter,
PathFilterMode,
SchemaValidation
// Other functions and types as needed...
} from 'object-deep-compare';
All functions are named exports, so you can import only the specific functions you need.
Schema Validation
The library offers optional schema validation to ensure objects match an expected structure before comparison. This helps catch structural issues early, ensuring that objects conform to expected schemas.
Basic Schema Validation Example
import {
CompareValuesWithDetailedDifferences,
SchemaValidation
} from 'object-deep-compare';
// Define a schema for user objects
const userSchema = {
id: 'string',
name: 'string',
age: 'number',
isActive: 'boolean',
metadata: {
createdAt: 'string',
updatedAt: 'string'
}
};
// Objects to compare
const user1 = {
id: '1001',
name: 'Alice',
age: 32,
isActive: true,
metadata: {
createdAt: '2023-01-01',
updatedAt: '2023-05-15'
}
};
const user2 = {
id: '1002',
name: 'Bob',
age: 'twenty-eight', // Wrong type - should be a number
isActive: true,
metadata: {
createdAt: '2023-02-10'
// Missing updatedAt field
}
};
// Set validation options
const schemaValidation: SchemaValidation = {
firstObjectSchema: userSchema,
secondObjectSchema: userSchema,
throwOnValidationFailure: true // Will throw an error if validation fails
};
try {
// Compare with schema validation
const differences = CompareValuesWithDetailedDifferences(
user1,
user2,
'',
{ schemaValidation }
);
console.log('Differences:', differences);
} catch (error) {
console.error('Schema validation failed:', error.message);
console.log('Validation result:', error.validationResult);
/*
ValidationResult will contain:
{
firstObjectValid: true,
secondObjectValid: false,
secondObjectErrors: [
'Property age should be of type number but got string',
'Missing required property: metadata.updatedAt'
]
}
*/
}
Schema Format
The schema definition is a simple object structure where:
- String values represent expected types:
'string'
,'number'
,'boolean'
,'object'
,'array'
, etc. - Use
'any'
to skip type checking for a property - Use objects for nested structure validation
- Use arrays with a single object to define schemas for array items
Array Schema Example:
// Schema for an array of user objects
const usersSchema = [
{
id: 'string',
name: 'string',
age: 'number'
}
];
// Or using array<type> notation
const tagsSchema = 'array<string>';
Manual Schema Validation
You can validate objects against schemas without performing comparisons:
import { ValidateObjectsAgainstSchemas, SchemaValidation } from 'object-deep-compare';
const schema = {
id: 'string',
items: 'array<object>'
};
const data = {
id: 123, // Wrong type
items: [{ name: 'Item 1' }]
};
const validationOptions: SchemaValidation = {
firstObjectSchema: schema,
throwOnValidationFailure: false // Get validation results instead of throwing
};
const result = ValidateObjectsAgainstSchemas(data, {}, validationOptions);
console.log(result);
/*
{
firstObjectValid: false,
secondObjectValid: true,
firstObjectErrors: ['Property id should be of type string but got number']
}
*/
API Reference
CompareProperties
This method compares the properties of two objects. It returns all the different and common properties between the two objects.
Parameters:
firstObject
- First object to comparesecondObject
- Second object to compare
Returns:
- An object with two arrays:
differences
: Properties that exist in the first object but not in the secondcommon
: Properties that exist in both objects
Example:
const firstObject = {
foo: 1,
bar: 2
};
const secondObject = {
foo: 2,
};
const { CompareProperties } = require('object-deep-compare');
// Or using ES modules: import { CompareProperties } from 'object-deep-compare';
const result = CompareProperties(firstObject, secondObject);
console.log(result);
/*
Will return:
{
differences: ['bar'],
common: ['foo']
}
*/
CompareArrays
This method compares two arrays for equality. It returns true or false.
Parameters:
firstArray
- First array to comparesecondArray
- Second array to compareoptions
(optional) - Comparison optionsstrict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate array structures before comparison
Returns:
boolean
: true if arrays are equal, false otherwise
Example:
const firstArray = [1, 2];
const secondArray = [1, 2];
const { CompareArrays } = require('object-deep-compare');
// Or using ES modules: import { CompareArrays } from 'object-deep-compare';
const isEqual = CompareArrays(firstArray, secondArray);
console.log(isEqual); // true
// With options
const deepArray1 = [1, [2, [3, 4]]];
const deepArray2 = [1, [2, [3, 5]]];
const isEqualWithStrict = CompareArrays(
deepArray1,
deepArray2,
{ strict: true }
);
console.log(isEqualWithStrict); // false
CompareValuesWithConflicts
This method performs a deep comparison of two objects and returns an array of paths to properties that differ.
Parameters:
firstObject
- First object to comparesecondObject
- Second object to comparepathOfConflict
(optional) - Starting path for conflict (default: '')options
(optional) - Comparison optionsstrict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate object structures before comparison
Returns:
string[]
: Array of paths to properties that differ between the objects
Example:
const firstObject = {
nested: {
foo: 1,
bar: 2
}
};
const secondObject = {
nested: {
foo: 2,
bar: 4
}
};
const { CompareValuesWithConflicts } = require('object-deep-compare');
// Or using ES modules: import { CompareValuesWithConflicts } from 'object-deep-compare';
const conflicts = CompareValuesWithConflicts(firstObject, secondObject);
console.log(conflicts);
/*
Will return: ['nested.foo', 'nested.bar']
*/
// With options
const deepObject1 = { level1: { level2: { level3: { value: 42 } } } };
const deepObject2 = { level1: { level2: { level3: { value: 43 } } } };
const conflictsWithStrict = CompareValuesWithConflicts(
deepObject1,
deepObject2,
'',
{ strict: true }
);
console.log(conflictsWithStrict); // ['level1.level2.level3.value']
CompareValuesWithDetailedDifferences
This method performs a deep comparison of two objects and returns detailed information about each difference, including the type of difference and the actual values.
Parameters:
firstObject
- First object to comparesecondObject
- Second object to comparepathOfConflict
(optional) - Starting path for conflict (default: '')options
(optional) - Comparison optionsstrict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate object structures before comparison
Returns:
DetailedDifference[]
: Array of detailed difference objects, where each object includes:path
: Path to the property that differstype
: Type of difference ('added', 'removed', or 'changed')oldValue
: Original value (undefined for added properties)newValue
: New value (undefined for removed properties)
Example:
const firstObject = {
user: {
name: 'John',
age: 30,
roles: ['admin']
}
};
const secondObject = {
user: {
name: 'John',
age: 31,
location: 'New York',
roles: ['admin', 'editor']
}
};
const { CompareValuesWithDetailedDifferences } = require('object-deep-compare');
// Or using ES modules: import { CompareValuesWithDetailedDifferences } from 'object-deep-compare';
const detailedDiffs = CompareValuesWithDetailedDifferences(firstObject, secondObject);
console.log(detailedDiffs);
/*
Will return: [
{
path: 'user.age',
type: 'changed',
oldValue: 30,
newValue: 31
},
{
path: 'user.location',
type: 'added',
oldValue: undefined,
newValue: 'New York'
},
{
path: 'user.roles',
type: 'changed',
oldValue: ['admin'],
newValue: ['admin', 'editor']
}
]
*/
ValidateObjectsAgainstSchemas
Validates objects against schema definitions without performing comparisons.
Parameters:
firstObject
- First object to validatesecondObject
- Second object to validateschemaValidation
- Schema validation optionsfirstObjectSchema
- Schema for the first objectsecondObjectSchema
- Schema for the second objectthrowOnValidationFailure
- Whether to throw an error if validation fails (default: false)
Returns:
SchemaValidationResult
: Object with validation resultsfirstObjectValid
- Boolean indicating if first object is validsecondObjectValid
- Boolean indicating if second object is validfirstObjectErrors
- Array of validation errors for first object (if any)secondObjectErrors
- Array of validation errors for second object (if any)
Example:
import { ValidateObjectsAgainstSchemas, SchemaValidation } from 'object-deep-compare';
const userSchema = {
id: 'string',
name: 'string',
age: 'number',
roles: 'array<string>'
};
const user = {
id: '1234',
name: 'John Doe',
age: 'thirty', // Should be a number
roles: ['admin', 'user']
};
const validationOptions: SchemaValidation = {
firstObjectSchema: userSchema,
throwOnValidationFailure: false
};
const result = ValidateObjectsAgainstSchemas(user, {}, validationOptions);
console.log(result);
/*
{
firstObjectValid: false,
secondObjectValid: true,
firstObjectErrors: ['Property age should be of type number but got string']
}
*/
Type-Safe Comparison Functions
The library now offers enhanced type safety with the following features:
- TypeScript type guards for better type inference
- Support for comparing objects with different but compatible types
- Better type inference for comparison results
- Detailed type information in comparison results
TypeSafeCompareArrays
This method compares two arrays with type information.
Parameters:
firstArray
- First array to comparesecondArray
- Second array to compareoptions
(optional) - Comparison options:strict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate array structures before comparison
Returns:
TypedComparisonResult<T, U>
: Object with:isEqual
: Boolean indicating if arrays are equalfirstType
: Type of the first arraysecondType
: Type of the second array
Example:
const stringArray = ['a', 'b', 'c'];
const numberArray = [1, 2, 3];
const mixedArray = ['a', 2, true];
const { TypeSafeCompareArrays } = require('object-deep-compare');
// Or using ES modules: import { TypeSafeCompareArrays } from 'object-deep-compare';
// Compare arrays of different types
const result = TypeSafeCompareArrays(stringArray, numberArray);
console.log(result);
/* Will return:
{
isEqual: false,
firstType: 'Array<string>',
secondType: 'Array<number>'
}
*/
// With includeTypeInfo option
const detailedResult = TypeSafeCompareArrays(stringArray, mixedArray, {
includeTypeInfo: true
});
console.log(detailedResult);
/* Will return:
{
isEqual: false,
firstType: 'Array<string>',
secondType: 'Array<string|number|boolean>'
}
*/
TypeSafeCompareObjects
This method compares two objects and supports objects with different but compatible types.
Parameters:
firstObject
- First object to comparesecondObject
- Second object to compareoptions
(optional) - Type-safe comparison options:strict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate object structures before comparisonpropertyMapping
: Maps properties from the first object to equivalent properties in the secondincludeTypeInfo
: Whether to include type information in the results (default: false)customComparators
: Custom comparator functions for specific property paths
Returns:
TypedComparisonResult<T, U>
: Object with:isEqual
: Boolean indicating if objects are equalfirstType
: Type of the first objectsecondType
: Type of the second object
Example:
// Different but compatible object types
interface User {
id: string;
name: string;
age: number;
}
interface Employee {
employeeId: string;
fullName: string;
age: number;
department: string;
}
const user: User = {
id: '1001',
name: 'John Doe',
age: 30
};
const employee: Employee = {
employeeId: '1001',
fullName: 'John Doe',
age: 30,
department: 'Engineering'
};
const { TypeSafeCompareObjects } = require('object-deep-compare');
// Or using ES modules: import { TypeSafeCompareObjects } from 'object-deep-compare';
// Using property mapping to compare objects with different structures
const result = TypeSafeCompareObjects(user, employee, {
propertyMapping: {
id: 'employeeId',
name: 'fullName'
},
includeTypeInfo: true
});
console.log(result);
/* Will return:
{
isEqual: true,
firstType: 'User',
secondType: 'Employee'
}
*/
// With custom comparator for specific properties
const customResult = TypeSafeCompareObjects(user, employee, {
propertyMapping: {
id: 'employeeId',
name: 'fullName'
},
customComparators: {
// Case-insensitive string comparison for name fields
'name': (val1, val2) => val1.toLowerCase() === val2.toLowerCase()
}
});
console.log(customResult.isEqual); // true
TypeSafeCompareValuesWithDetailedDifferences
This method performs a deep comparison of two objects and returns detailed differences with type information.
Parameters:
firstObject
- First object to comparesecondObject
- Second object to compareoptions
(optional) - Type-safe comparison options:strict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate object structures before comparisonpropertyMapping
: Maps properties from the first object to equivalent properties in the secondincludeTypeInfo
: Whether to include type information in the results (default: false)customComparators
: Custom comparator functions for specific property paths
Returns:
TypedDetailedDifference[]
: Array of detailed differences with type information:- All properties from
DetailedDifference
oldValueType
: Type of the old valuenewValueType
: Type of the new value
- All properties from
Example:
interface Product {
id: string;
name: string;
price: number;
stock?: number;
}
const oldProduct: Product = {
id: 'prod-001',
name: 'Original Product',
price: 29.99
};
const newProduct: Product = {
id: 'prod-001',
name: 'Updated Product',
price: 39.99,
stock: 100
};
const { TypeSafeCompareValuesWithDetailedDifferences } = require('object-deep-compare');
// Or using ES modules: import { TypeSafeCompareValuesWithDetailedDifferences } from 'object-deep-compare';
const differences = TypeSafeCompareValuesWithDetailedDifferences(oldProduct, newProduct, {
includeTypeInfo: true
});
console.log(differences);
/* Will return:
[
{
path: 'name',
type: 'changed',
oldValue: 'Original Product',
newValue: 'Updated Product',
oldValueType: 'string',
newValueType: 'string'
},
{
path: 'price',
type: 'changed',
oldValue: 29.99,
newValue: 39.99,
oldValueType: 'number',
newValueType: 'number'
},
{
path: 'stock',
type: 'added',
oldValue: undefined,
newValue: 100,
oldValueType: 'undefined',
newValueType: 'number'
}
]
*/
ObjectsAreEqual
Type guard function that checks if two objects are equal and narrows types in conditional branches.
Parameters:
firstObject
- First object to comparesecondObject
- Second object to compareoptions
(optional) - Comparison options:strict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate object structures before comparison
Returns:
- Type predicate indicating if the objects are equal (narrows type to intersection)
Example:
interface Shape {
type: string;
color: string;
}
interface Circle extends Shape {
type: 'circle';
radius: number;
}
interface Square extends Shape {
type: 'square';
sideLength: number;
}
function processShape(shape1: Shape, shape2: Shape) {
const { ObjectsAreEqual } = require('object-deep-compare');
// Or using ES modules: import { ObjectsAreEqual } from 'object-deep-compare';
// ObjectsAreEqual acts as a type guard
if (ObjectsAreEqual(shape1, shape2)) {
// TypeScript now knows both shapes are equal
console.log('Shapes are equal:', shape1.type);
return true;
} else {
console.log('Shapes are different');
// TypeScript maintains the original types
return false;
}
}
const circle: Circle = { type: 'circle', color: 'red', radius: 10 };
const sameCircle: Circle = { type: 'circle', color: 'red', radius: 10 };
const differentCircle: Circle = { type: 'circle', color: 'blue', radius: 5 };
processShape(circle, sameCircle); // "Shapes are equal: circle"
processShape(circle, differentCircle); // "Shapes are different"
IsSubset
Checks if the second object is a subset of the first object.
Parameters:
firstObject
- Object to check againstsecondObject
- Object that should be a subsetoptions
(optional) - Comparison options:strict
- Whether to use strict equality (===) for comparing values (default: true)circularReferences
- How to handle circular references: 'error' or 'ignore' (default: 'error')pathFilter
- Configuration to include or exclude properties based on path patternsschemaValidation
- Schema validation options to validate object structures before comparison
Returns:
boolean
: True if second object is a subset of first object
Example:
const completeUser = {
id: '1001',
name: 'Jane Smith',
age: 28,
email: 'jane@example.com',
settings: {
theme: 'dark',
notifications: true,
privacyLevel: 'high'
}
};
const partialUser = {
id: '1001',
name: 'Jane Smith'
};
const partialSettings = {
settings: {
theme: 'dark'
}
};
const { IsSubset } = require('object-deep-compare');
// Or using ES modules: import { IsSubset } from 'object-deep-compare';
console.log(IsSubset(completeUser, partialUser)); // true
console.log(IsSubset(completeUser, partialSettings)); // true
// Non-matching subset
const nonMatchingUser = {
id: '1001',
name: 'Different Name'
};
console.log(IsSubset(completeUser, nonMatchingUser)); // false
// Extra properties
const extraPropsUser = {
id: '1001',
name: 'Jane Smith',
role: 'admin' // This property doesn't exist in completeUser
};
console.log(IsSubset(completeUser, extraPropsUser)); // false
GetCommonStructure
Gets the common structure between two objects.
Parameters:
firstObject
- First object to comparesecondObject
- Second object to compare
Returns:
Partial<CompatibleObject<T, U>>
: A new object containing only common properties
Example:
const user1 = {
id: 'user1',
name: 'Alice',
age: 30,
email: 'alice@example.com',
settings: {
theme: 'light',
notifications: true
}
};
const user2 = {
id: 'user2',
name: 'Bob',
age: 25,
role: 'admin',
settings: {
theme: 'dark',
privacyLevel: 'high'
}
};
const { GetCommonStructure } = require('object-deep-compare');
// Or using ES modules: import { GetCommonStructure } from 'object-deep-compare';
const common = GetCommonStructure(user1, user2);
console.log(common);
/* Will return:
{
id: 'user1', // Values from first object are used
name: 'Alice',
age: 30,
settings: {
theme: 'light'
}
}
*/
// The result contains only properties present in both objects,
// with nested objects showing their common structure
Advanced Usage
Handling Special Values
The library correctly handles special values like NaN
, null
, and undefined
:
const obj1 = { value: NaN };
const obj2 = { value: NaN };
const { CompareArrays } = require('object-deep-compare');
// Or using ES modules: import { CompareArrays } from 'object-deep-compare';
// NaN === NaN is false in JavaScript, but our library correctly identifies them as equal
const isEqual = CompareArrays(obj1, obj2);
console.log(isEqual); // true
Comparing Date Objects
Date objects are compared based on their time values:
const date1 = new Date('2023-01-01');
const date2 = new Date('2023-01-01');
const date3 = new Date('2023-01-02');
const { CompareArrays } = require('object-deep-compare');
// Or using ES modules: import { CompareArrays } from 'object-deep-compare';
const isEqual = CompareArrays(date1, date2);
console.log(isEqual); // true
const isNotEqual = CompareArrays(date1, date3);
console.log(isNotEqual); // false
Comparing RegExp Objects
RegExp objects are compared based on their source and flags:
const regex1 = /test/g;
const regex2 = /test/g;
const regex3 = /test/i;
const { CompareArrays } = require('object-deep-compare');
// Or using ES modules: import { CompareArrays } from 'object-deep-compare';
const isEqual = CompareArrays(regex1, regex2);
console.log(isEqual); // true
const isNotEqual = CompareArrays(regex1, regex3);
console.log(isNotEqual); // false
Handling Circular References
The library can detect and handle circular references in objects and arrays:
// Create objects with circular references
const obj1 = { a: 1, b: 2 };
obj1.self = obj1; // Self-reference
const obj2 = { a: 1, b: 2 };
obj2.self = obj2; // Self-reference
const { CompareValuesWithDetailedDifferences } = require('object-deep-compare');
// Or using ES modules: import { CompareValuesWithDetailedDifferences } from 'object-deep-compare';
// By default, circular references will throw an error
try {
const diffs = CompareValuesWithDetailedDifferences(obj1, obj2);
} catch (error) {
console.log(error.message); // "Circular reference detected at path: self"
}
// Use the circularReferences option to handle circular references gracefully
const options = { circularReferences: 'ignore' };
const diffs = CompareValuesWithDetailedDifferences(obj1, obj2, '', options);
console.log(diffs); // [] (empty array, objects are equal)
// Objects with the same structure but different values will still show differences
const obj3 = { a: 1, b: 3 }; // Different value for b
obj3.self = obj3;
const diffResults = CompareValuesWithDetailedDifferences(obj1, obj3, '', options);
console.log(diffResults[0].path); // "b"
Memoized Functions
The library provides memoized versions of all comparison functions for improved performance when comparing the same objects multiple times. Memoization caches the results of function calls based on their arguments, avoiding redundant computations.
MemoizedCompareProperties
Memoized version of CompareProperties
that caches results based on object references.
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, c: 3 };
const { MemoizedCompareProperties } = require('object-deep-compare');
// Or using ES modules: import { MemoizedCompareProperties } from 'object-deep-compare';
// First call computes the result
const result1 = MemoizedCompareProperties(obj1, obj2);
// Second call with same objects returns cached result
const result2 = MemoizedCompareProperties(obj1, obj2);
MemoizedCompareArrays
Memoized version of CompareArrays
that caches results based on array references and options.
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const options = { strict: true };
const { MemoizedCompareArrays } = require('object-deep-compare');
// Or using ES modules: import { MemoizedCompareArrays } from 'object-deep-compare';
// First call computes the result
const result1 = MemoizedCompareArrays(arr1, arr2, options);
// Second call with same arrays and options returns cached result
const result2 = MemoizedCompareArrays(arr1, arr2, options);
MemoizedCompareValuesWithConflicts
Memoized version of CompareValuesWithConflicts
that caches results based on object references, path, and options.
const obj1 = { nested: { value: 1 } };
const obj2 = { nested: { value: 2 } };
const path = '';
const options = { strict: true };
const { MemoizedCompareValuesWithConflicts } = require('object-deep-compare');
// Or using ES modules: import { MemoizedCompareValuesWithConflicts } from 'object-deep-compare';
// First call computes the result
const result1 = MemoizedCompareValuesWithConflicts(obj1, obj2, path, options);
// Second call with same parameters returns cached result
const result2 = MemoizedCompareValuesWithConflicts(obj1, obj2, path, options);
MemoizedCompareValuesWithDetailedDifferences
Memoized version of CompareValuesWithDetailedDifferences
that caches results for better performance.
const obj1 = { user: { name: 'John', age: 30 } };
const obj2 = { user: { name: 'John', age: 31 } };
const { MemoizedCompareValuesWithDetailedDifferences } = require('object-deep-compare');
// Or using ES modules: import { MemoizedCompareValuesWithDetailedDifferences } from 'object-deep-compare';
// First call computes the result
const result1 = MemoizedCompareValuesWithDetailedDifferences(obj1, obj2);
// Second call with same objects returns cached result
const result2 = MemoizedCompareValuesWithDetailedDifferences(obj1, obj2);
Path Filtering
You can include or exclude specific properties from comparison using the pathFilter
option.
PathFilter interface:
interface PathFilter {
patterns: string[]; // Array of path patterns to match
mode?: 'include' | 'exclude'; // Whether to include or exclude matched paths (default: 'exclude')
}
Path pattern types:
- Exact paths: Match a specific property path (e.g.,
'user.name'
) - Leading dot paths: Match any property with the specified name at any level (e.g.,
'.timestamp'
matches'timestamp'
,'user.timestamp'
,'logs.entry.timestamp'
, etc.) - Wildcard paths: Use
*
to match any property name in a path (e.g.,'user.*.created'
matches'user.profile.created'
,'user.settings.created'
, etc.)
Examples:
Ignore all timestamp properties:
const options = {
pathFilter: {
patterns: ['.timestamp', '.createdAt', '.updatedAt'],
mode: 'exclude' // This is the default mode
}
};
const { CompareValuesWithConflicts } = require('object-deep-compare');
// Or using ES modules: import { CompareValuesWithConflicts } from 'object-deep-compare';
const differences = CompareValuesWithConflicts(obj1, obj2, '', options);
Only compare specific fields:
const options = {
pathFilter: {
patterns: ['user.name', 'user.email', 'settings.*'],
mode: 'include'
}
};
const { CompareValuesWithDetailedDifferences } = require('object-deep-compare');
// Or using ES modules: import { CompareValuesWithDetailedDifferences } from 'object-deep-compare';
const differences = CompareValuesWithDetailedDifferences(obj1, obj2, '', options);
Compare everything except auto-generated IDs:
const options = {
pathFilter: {
patterns: ['.id', '.uuid', '*.id'],
mode: 'exclude'
}
};
const { CompareArrays } = require('object-deep-compare');
// Or using ES modules: import { CompareArrays } from 'object-deep-compare';
const isEqual = CompareArrays(array1, array2, options);
Dependencies
No runtime dependencies!
Dev Dependencies
typescript
jest
ts-jest
@types/jest
License
MIT © Dean Dumitru
🔧 Developed by ByteBoost
This library is maintained by ByteBoost - a software development company that builds high-quality, performant solutions for businesses of all sizes. Need custom development, performance optimization, or technical consulting? Contact us to elevate your tech.