Skip to content

Commit 009229d

Browse files
committed
Revert previous assertion as it introduced a regression
It seems reasonable to assert that keys shouldn't be undefined, since keys are supposed to be of type PropertyKey (string | number | symbol). But in practice, JavaScript allows undefined as a key by implicitly converting it to the string "undefined". This caused a regression specifically in the `groupBy` function, where the grouper callback can return undefined for some items. That behavior was previously supported and is now broken by the assertion. Long-term, it probably makes sense to tighten this up and only allow real PropertyKeys, but that’ll need a more careful cleanup.
1 parent 8561fcb commit 009229d

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

__tests__/groupBy.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ describe('groupBy', () => {
7575
expect(group.toJS()).toEqual({ odd: [1, 3, 5], even: [2, 4, 6] });
7676
});
7777

78+
it('allows `undefined` as a key', () => {
79+
const group = Seq([1, 2, 3, 4, 5, 6]).groupBy((x) =>
80+
x % 2 ? undefined : 'even'
81+
);
82+
expect(group.toJS()).toEqual({ undefined: [1, 3, 5], even: [2, 4, 6] });
83+
});
84+
7885
it('groups indexed sequences, maintaining indicies when keyed sequences', () => {
7986
const group = Seq([1, 2, 3, 4, 5, 6]).groupBy((x) => x % 2);
8087

src/functional/updateIn.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,11 @@ function updateInDeeply<
180180
}
181181
const key = keyPath[i];
182182

183-
if (typeof key === 'undefined') {
184-
throw new TypeError(
185-
'Index can not be undefined in updateIn(). This should not happen'
186-
);
187-
}
183+
const nextExisting = wasNotSet
184+
? NOT_SET
185+
: // @ts-expect-error key might be undefined which is not allowed in the type but works in practice
186+
get(existing, key, NOT_SET);
188187

189-
const nextExisting = wasNotSet ? NOT_SET : get(existing, key, NOT_SET);
190188
const nextUpdated = updateInDeeply(
191189
nextExisting === NOT_SET ? inImmutable : isImmutable(nextExisting),
192190
// @ts-expect-error mixed type
@@ -196,10 +194,12 @@ function updateInDeeply<
196194
notSetValue,
197195
updater
198196
);
197+
199198
return nextUpdated === nextExisting
200199
? existing
201200
: nextUpdated === NOT_SET
202-
? remove(existing, key)
201+
? // @ts-expect-error key might be undefined which is not allowed in the type but works in practice
202+
remove(existing, key)
203203
: set(
204204
wasNotSet ? (inImmutable ? emptyMap() : {}) : existing,
205205
key,

0 commit comments

Comments
 (0)