isShallowEqual function
Checks whether two values are equal at the first level, with Object.is: skips an update when a new object carries the same values as the previous one.
ts
import { isShallowEqual } from 'utils';Signature
ts
export function isShallowEqual(a: unknown, b: unknown): booleanParameters
| Name | Description |
|---|---|
a | The first value. |
b | The second value. |
Returns
true when both values are shallowly equal; nested objects are compared by reference.
Example
ts
isShallowEqual({ x: 1, y: 2 }, { y: 2, x: 1 }); // true
isShallowEqual({ p: { x: 1 } }, { p: { x: 1 } }); // falseTests
Line coverage: 100 %.
- ✅ compares 1 and 1 as true
- ✅ compares null and null as true
- ✅ compares 0 and 0 as false
- ✅ compares "a" and "b" as false
- ✅ compares null and null as true
- ✅ compares null and {} as false
- ✅ compares {"x":1,"y":2} and {"y":2,"x":1} as true
- ✅ compares {"x":1} and {"x":1,"y":2} as false
- ✅ compares {"x":1} and {"x":1} as false
- ✅ compares {"x":1} and {"x":2} as false
- ✅ compares [1,2] and [1,2] as true
- ✅ compares [1,2] and {"0":1,"1":2} as false
- ✅ compares {"p":{"x":1}} and {"p":{"x":1}} as false
- ✅ accepts shared nested references
Source
src/object/is-shallow-equal.ts (on GitHub)
Uses
isObject: Checks whether a value is a non-null object: plain object, array, class instance, date…isRecordaccepts plain objects only.
Files it needs
src/object/is-shallow-equal.ts imports, directly or not:
Source code
ts
import { isObject } from '../guard';
/**
* Checks whether two values are equal at the first level, with `Object.is`: skips an update when a new object carries the
* same values as the previous one.
*
* @param a - The first value.
* @param b - The second value.
* @returns `true` when both values are shallowly equal; nested objects are compared by reference.
* @example
* isShallowEqual({ x: 1, y: 2 }, { y: 2, x: 1 }); // true
* isShallowEqual({ p: { x: 1 } }, { p: { x: 1 } }); // false
*/
export function isShallowEqual(a: unknown, b: unknown): boolean {
if (Object.is(a, b)) {
return true;
}
if (!isObject(a) || !isObject(b) || Array.isArray(a) !== Array.isArray(b)) {
return false;
}
const keys = Object.keys(a);
return (
keys.length === Object.keys(b).length &&
keys.every((key) => Object.hasOwn(b, key) && Object.is(Reflect.get(a, key), Reflect.get(b, key)))
);
}Test file
ts
import { isShallowEqual } from './is-shallow-equal';
describe(isShallowEqual, () => {
it.for([
[1, 1, true],
[NaN, NaN, true],
[0, -0, false],
['a', 'b', false],
[null, null, true],
[null, {}, false],
[{ x: 1, y: 2 }, { y: 2, x: 1 }, true],
[{ x: 1 }, { x: 1, y: 2 }, false],
[{ x: 1, y: undefined }, { x: 1, z: undefined }, false],
[{ x: 1 }, { x: 2 }, false],
[[1, 2], [1, 2], true],
[[1, 2], { 0: 1, 1: 2 }, false],
[{ p: { x: 1 } }, { p: { x: 1 } }, false],
] as const)('compares %j and %j as %s', ([a, b, expected]) => {
expect(isShallowEqual(a, b)).toBe(expected);
});
it('accepts shared nested references', () => {
const point = { x: 1 };
expect(isShallowEqual({ point }, { point })).toBe(true);
});
});Keywords: is, shallow, equal, objects, function