-
Notifications
You must be signed in to change notification settings - Fork 511
Description
Proposal: Improve isMatch behavioral consistency
Hi!
While fixing several isMatch issue(#1399), I found cases where Lodash and compat show different results:
| Case | Lodash | compat |
|---|---|---|
| Some partial-match cases | ❌ incorrect | ✅ correct |
Since compat’s core goal is to help migration by providing full behavioral parity with Lodash,
this mismatch should be fixed — compat should produce the same result as Lodash.
✅ However, the behavior in Lodash itself is buggy
❌ So simply aligning compat to Lodash is also not ideal for users
In other words…
We need to fix the mismatch
but also fix the root cause that causes confusion
🔍 Example
Especially with Set / Map subset matching, Lodash returns unexpected results.
Additionally, since Lodash is not maintained by Toss,
it can be difficult to decide which behavior compat should follow in cases like this.
Related Lodash Issue (#3887)
Lodash maintainer’s reasoning:
“When there's nothing to match, everything matches.”
However, the actual behavior varies:
| target | source | Lodash result |
|---|---|---|
| {a:1} | {} | true ✅ |
| {a:1} | null | true ✅ |
| {a:1} | 123 | true ✅ |
| {a:1} | '' | true ✅ |
| {a:1} | 'abc' | false |
- Same condition → different results depending on recursion depth
- Primitive values always match (except strings)
Since this behavior is not clearly documented,
it can be unintuitive and difficult to predict —
meaning users may reasonably be confused by these results.
🤔 Depth-dependent behavior
isMatch('bar', {}) // true (top level)
isMatch({ value: 'bar' }, { value: {} }) // false (nested)❌ difficult for users to anticipate
✅ Proposal
| compat direction | es-toolkit enhancement |
|---|---|
| Follow Lodash behavior exactly | Provide a clearer and more consistent alternative API |
| Ensures seamless migration experience | Improves correctness & predictability for users |
The new API could:
- Remove “primitive source always matches” rule
- Apply consistent subset rules for Set / Map
- Avoid depth-dependent behavior
- Clearly follow:
source ⊆ target → true
🙏 Request for maintainer input
To support smooth migration, compat should align with Lodash’s behavior —
but preserving behavior that is buggy or confusing in practice may lead to unintended issues.
So I’d like to propose introducing a new, more predictable isMatch-style API in es-toolkit, independent from Lodash’s quirks.
In isMatch(target, source), the fact that results can differ based on recursion depth — and that primitive source values almost always return true without clear documentation — can be confusing for users.
These implicit and inconsistent rules make it difficult to confidently understand what it means for the source to be “matched” by the target in real-world scenarios.
A new API that provides consistent and intuitive matching rules would significantly improve the developer experience.
Would this be something worth addressing in es-toolkit?
I’d love to hear your thoughts! 😊
If this proposal sounds reasonable,
I would be happy to try implementing an initial version —
and would greatly appreciate any guidance or feedback along the way! 🙌