fix: Treat decimal/negative/padded numbers as object keys, not array indexes#526
Conversation
📝 WalkthroughWalkthroughReplaces ad-hoc numeric checks in Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 Comment |
|
@erikras-gilfoyle-agent please fix and push. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/structure/setIn.test.ts`:
- Around line 260-265: The failing test assumes dots are literal keys but toPath
treats dots as separators, causing nested numeric-index arrays; remove or
replace this test in src/structure/setIn.test.ts — either delete the "5.1.1"
test case or replace it with a direct unit test against setInRecursor (pass a
pre-built path array like ["5.1.1"] and check it sets { "5.1.1": "value" }) so
you don't rely on toPath behavior; keep other tests (e.g., -1 and 01) unchanged.
…indexes
Fixes react-final-form#1042
Problem:
Keys like "5.1.1", "-1", or "01" were incorrectly treated as array
indexes because the code only checked isNaN(Number(key)), which returns
false for these values.
For example:
- Number("5.1.1") = 5.1 (not NaN, so treated as array index)
- Number("-1") = -1 (not NaN, so treated as array index)
- Number("01") = 1 (not NaN, treated as array index)
This caused errors when trying to use these as object keys.
Root Cause:
The isNaN(Number(key)) check only verifies if the key can be parsed as
a number, but doesn't verify if it's a valid array index. A valid array
index must be:
1. A non-negative integer
2. In canonical form (no leading zeros, no decimals)
Solution:
Created isValidArrayIndex() helper that checks:
1. Not NaN
2. Is an integer (Number.isInteger)
3. Is non-negative (>= 0)
4. String representation matches (String(num) === key)
This ensures only valid array indexes like "0", "1", "42" are treated
as arrays, while "5.1.1", "-1", "01" are treated as object keys.
Changes:
- src/structure/setIn.ts:
- Added isValidArrayIndex() helper function
- Replaced isNaN(Number(key)) checks with isValidArrayIndex(key)
- src/structure/setIn.test.ts:
- Added tests for decimal numbers ("5.1.1")
- Added tests for negative numbers ("-1")
- Added tests for padded numbers ("01")
- Verified valid integers still work as array indexes
Impact:
✅ Decimal-separated keys like "5.1.1" now work as object keys
✅ Negative numbers like "-1" treated as object keys
✅ Padded numbers like "01" treated as object keys
✅ Valid integers ("0", "1", "42") still work as array indexes
✅ No breaking changes - only fixes incorrect behavior
307f654 to
351b846
Compare
erikras-richard-agent
left a comment
There was a problem hiding this comment.
LGTM! The isValidArrayIndex() helper is well-designed — handles all edge cases:
- Decimals (
5.1) → object key ✅ - Negatives (
-1) → object key ✅ - Padded (
01) → object key ✅ - Valid integers (
0,42) → array index ✅
The String(num) === key check is clever for catching padded numbers. Good test coverage. ✅
|
Published in |
Summary
Fixes react-final-form#1042
Allows using decimal-separated numbers like
"5.1.1", negative numbers like"-1", and padded numbers like"01"as object keys instead of incorrectly treating them as array indexes.Problem
Reported Issue: Keys like
"5.1.1"cannot be used in forms becausesetIn()incorrectly treats them as array indexes and throws errors.Root cause: The check
isNaN(Number(key))only verifies if a string can be parsed as a number, but doesn't check if it's a valid array index.Examples of the bug:
This caused
setIn()to try creating arrays for these keys, which failed because:"5.1.1"parses to5.1(not a valid array index)"-1"is negative (not a valid array index)"01"!=="1"(canonical form mismatch)Solution
Created
isValidArrayIndex()helper that checks if a key is a valid array index:Valid array indexes:
"0","1","42"✅Object keys (not array indexes):
"5.1.1","-1","01","3.14"✅Code Changes
Before:
After:
Testing
Added comprehensive tests:
Impact
✅ Fixes the reported bug
"5.1.1"now work correctly✅ More correct behavior
"-1"treated as object keys (not array indexes)"01"treated as object keys (not array indexes)✅ No breaking changes
"0","1","42") still work identically✅ Minimal code change
Use Case
This is useful for forms with version numbers, coordinates, or other structured identifiers:
Fixes react-final-form#1042
Summary by CodeRabbit