microdiff
microdiff copied to clipboard
Inconsistent diff Behavior for Object-derived Type Changes
Issue Summary:
The diff
function exhibits inconsistent behavior when comparing changes between properties of different Object-derived types such as Array, Set, Map, etc. It appears to misidentify certain type changes as property additions/removals rather than recognizing a complete change in the property's type.
Example:
const changes = diff({ data: [] }, { data: { val: 'test' } });
// Returned: [ { type: 'CREATE', path: ['data', 'val'], value: 'test' } ]
// Expected: [ { type: 'CHANGE', path: ['data'], value: { val: 'test' } } ]
Description of the bug:
When the diff
function encounters property values that have changed type—specifically from an Array, Set, Map, Error, Promise, or Proxy to another object type—it incorrectly reports the changes as individual property mutations (CREATE
and REMOVE
) rather than recognizing a CHANGE
in the entire value for the key.
For types such as Function, Date, and RegExp, when these are nested property values, the change is correctly detected as a CHANGE
. However, when types like Array, Set, or Map are nested, they do not receive the same treatment.
Additional Context:
There's a discrepancy based on whether the Object-derived types are passed directly as an argument to diff or nested. For example:
const diffArgument = diff(new Date(), { data: 'test' });
// Returned: [ { type: 'CREATE', path: ['data'], value: 'test' } ]
const diffObjValue = diff({ data: new Date() }, { data: { val: 'test' } });
// Returned: [ { type: 'CHANGE', path: ['data'], value: { val: 'test' }, oldValue: '2023-11-06T02:40:05.198Z' }]
It is not clear if this behavior is intentional or an oversight. Clarification in the documentation would be beneficial.