From 9593306b895f82e3530235faee2f21665affef06 Mon Sep 17 00:00:00 2001 From: chuenchen309 <48723787+chuenchen309@users.noreply.github.com> Date: Sun, 19 Jul 2026 15:41:34 +0800 Subject: [PATCH 1/2] fix(compat/omit): treat a key array as a single deep path to match lodash omit iterated the elements of an array-form key and unset each as its own top-level key, so omit({ a: { b: 1, c: 2 }, d: 3 }, [['a', 'b']]) returned { d: 3 } (dropping top-level a and b) instead of lodash's { a: { c: 2 }, d: 3 } (dropping the deep path a.b). The sibling pick already treats a key array as a single deep path. When the key is a real Array, pass it to unset once as a deep path. Array-like/arguments keys keep being treated as separate keys. Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: chuenchen309 <48723787+chuenchen309@users.noreply.github.com> --- src/compat/object/omit.spec.ts | 8 ++++++++ src/compat/object/omit.ts | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/compat/object/omit.spec.ts b/src/compat/object/omit.spec.ts index 016d1d535a..de7a918841 100644 --- a/src/compat/object/omit.spec.ts +++ b/src/compat/object/omit.spec.ts @@ -36,6 +36,14 @@ describe('omit', () => { expect(actual).toEqual({ a: { b: 2 } }); }); + it('should treat a key array as a single deep path', () => { + const object = { a: { b: 1, c: 2 }, d: 3 }; + // @ts-expect-error - path is a string + expect(omit(object, [['a', 'b']])).toEqual({ a: { c: 2 }, d: 3 }); + // @ts-expect-error - path is a string + expect(omit(object, [['a', 'b'], 'd'])).toEqual({ a: { c: 2 } }); + }); + it('should omit a key over a path', () => { const object = { 'a.b': 1, a: { b: 2 } }; diff --git a/src/compat/object/omit.ts b/src/compat/object/omit.ts index 7032807ea4..d49f43d4fe 100644 --- a/src/compat/object/omit.ts +++ b/src/compat/object/omit.ts @@ -87,18 +87,19 @@ export function omit(obj: T | null | undefined, ...keysArr: Ar const result = cloneInOmit(obj, keysArr); for (let i = 0; i < keysArr.length; i++) { - let keys = keysArr[i]; + const keys = keysArr[i]; switch (typeof keys) { case 'object': { - if (!Array.isArray(keys)) { - keys = Array.from(keys as PropertyKey[]); - } - - for (let j = 0; j < keys.length; j++) { - const key = keys[j]; - - unset(result, key); + if (Array.isArray(keys)) { + // A key array is a single deep path (e.g. `['a', 'b']` targets `a.b`), matching lodash. + unset(result, keys); + } else { + const arrayLikeKeys = Array.from(keys as PropertyKey[]); + + for (let j = 0; j < arrayLikeKeys.length; j++) { + unset(result, arrayLikeKeys[j]); + } } break; From cabcb23d30a8151d4dbfa70f9b743bea63cc3482 Mon Sep 17 00:00:00 2001 From: chuenchen309 <48723787+chuenchen309@users.noreply.github.com> Date: Mon, 20 Jul 2026 02:32:30 +0800 Subject: [PATCH 2/2] test(bundle-size): update omit compat snapshot for deep-path key-array fix The compat/omit change adds a few bytes; refresh the bundle-size snapshot to match. Size taken from CI. Co-Authored-By: Claude Opus 4.8 (1M context) --- benchmarks/bundle-size/omit.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/bundle-size/omit.spec.ts b/benchmarks/bundle-size/omit.spec.ts index cb6b87bccf..60daff40cd 100644 --- a/benchmarks/bundle-size/omit.spec.ts +++ b/benchmarks/bundle-size/omit.spec.ts @@ -14,6 +14,6 @@ describe('omit bundle size', () => { it('es-toolkit/compat', async () => { const bundleSize = await getBundleSize('es-toolkit/compat', 'omit'); - expect(bundleSize).toMatchInlineSnapshot(`8614`); + expect(bundleSize).toMatchInlineSnapshot(`8621`); }); });