From 80f4ce2d036f0f973b55a7e227a986498d1e6160 Mon Sep 17 00:00:00 2001 From: sen2y Date: Wed, 1 Oct 2025 21:29:20 +0900 Subject: [PATCH 1/3] fix(isMatch): handle primitive targets with object source patterns correctly --- src/compat/predicate/isMatch.spec.ts | 18 ++++++++++++++++++ src/compat/predicate/isMatchWith.ts | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/src/compat/predicate/isMatch.spec.ts b/src/compat/predicate/isMatch.spec.ts index 073ca4d79..58213df20 100644 --- a/src/compat/predicate/isMatch.spec.ts +++ b/src/compat/predicate/isMatch.spec.ts @@ -316,6 +316,24 @@ describe('isMatch', () => { delete numberProto.b; }); + it('should return `false` when target is primitive and source is object with undefined values (Issue #1399)', () => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + expect(isMatch('bar', { anyKey: undefined })).toBe(false); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + expect(isMatch(123, { anyKey: undefined })).toBe(false); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + expect(isMatch(true, { anyKey: undefined })).toBe(false); + }); + + it('should return `false` when target is primitive and source is empty object nested (Issue #1399)', () => { + expect(isMatch({ value: 'bar' }, { value: {} })).toBe(false); + expect(isMatch({ value: 123 }, { value: {} })).toBe(false); + expect(isMatch({ value: true }, { value: {} })).toBe(false); + }); + it(`should return \`false\` when \`object\` is nullish`, () => { // eslint-disable-next-line no-sparse-arrays const values = [, null, undefined]; diff --git a/src/compat/predicate/isMatchWith.ts b/src/compat/predicate/isMatchWith.ts index 6c2a7f192..990da6228 100644 --- a/src/compat/predicate/isMatchWith.ts +++ b/src/compat/predicate/isMatchWith.ts @@ -211,9 +211,16 @@ function isObjectMatch( } if (keys.length === 0) { + if (stack && stack.size > 0 && !isObject(target)) { + return false; + } return true; } + if (!isObject(target)) { + return false; + } + if (stack && stack.has(source)) { return stack.get(source) === target; } From 2346eeae030f1c9343969b661dc22f8075fbb0f4 Mon Sep 17 00:00:00 2001 From: Sojin Park Date: Fri, 24 Oct 2025 12:32:08 +0900 Subject: [PATCH 2/3] Update src/compat/predicate/isMatchWith.ts --- src/compat/predicate/isMatchWith.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/compat/predicate/isMatchWith.ts b/src/compat/predicate/isMatchWith.ts index 990da6228..1fa02672c 100644 --- a/src/compat/predicate/isMatchWith.ts +++ b/src/compat/predicate/isMatchWith.ts @@ -210,17 +210,14 @@ function isObjectMatch( return keys.length === 0; } - if (keys.length === 0) { - if (stack && stack.size > 0 && !isObject(target)) { - return false; - } - return true; - } - if (!isObject(target)) { return false; } + if (keys.length === 0) { + return true; + } + if (stack && stack.has(source)) { return stack.get(source) === target; } From df2b90783bb9905f8b22539f7f7fc5362526a713 Mon Sep 17 00:00:00 2001 From: Sojin Park Date: Fri, 24 Oct 2025 12:35:31 +0900 Subject: [PATCH 3/3] Update src/compat/predicate/isMatchWith.ts --- src/compat/predicate/isMatchWith.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compat/predicate/isMatchWith.ts b/src/compat/predicate/isMatchWith.ts index 1fa02672c..4287a9554 100644 --- a/src/compat/predicate/isMatchWith.ts +++ b/src/compat/predicate/isMatchWith.ts @@ -207,7 +207,10 @@ function isObjectMatch( const keys = Object.keys(source as any); if (target == null) { - return keys.length === 0; + if (stack && stack.size > 0 && !isObject(target)) { + return false; + } + return true; } if (!isObject(target)) {