8000 Fix `Uncaught TypeError: keyPath.slice is not a function` for ArrayLi… · immutable-js/immutable-js@2a62b65 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2a62b65

Browse files
authored
Fix Uncaught TypeError: keyPath.slice is not a function for ArrayLike method (#2065)
1 parent 96bf1f9 commit 2a62b65

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

__tests__/updateIn.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,54 @@ describe('updateIn', () => {
7272
);
7373
});
7474

75+
it('handle ArrayLike objects that are nor Array not immutable Collection', () => {
76+
class CustomArrayLike<T> implements ArrayLike<T> {
77+
readonly length: number;
78+
[n: number]: T;
79+
80+
constructor(...values: Array<T>) {
81+
this.length = values.length;
82+
83+
for (let i = 0; i < values.length; i++) {
84+
this[i] = values[i];
85+
}
86+
}
87+
88+
// Define other methods if needed, but do not include the `slice` method
89+
// For example, you can define a method to set values
90+
set(index: number, value: T): void {
91+
if (index < 0 || index >= this.length) {
92+
throw new RangeError('Index out of bounds');
93+
}
94+
95+
this[index] = value;
96+
}
97+
98+
// Define a method to get values
99+
get(index: number): T {
100+
if (index < 0 || index >= this.length) {
101+
throw new RangeError('Index out of bounds');
102+
}
103+
104+
return this[index];
105+
}
106+
}
107+
108+
// create an ArrayLike
109+
const customArray = new CustomArrayLike<number>(10, 20);
110+
111+
// code that works perfectly
112+
expect(
113+
// @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection<K> | ArrayLike<K>;
114+
updateIn({ 10: { 20: 'a' } }, customArray, (v) => `${v.toUpperCase()}`)
115+
).toEqual({ 10: { 20: 'A' } });
116+
117+
expect(() =>
118+
// @ts-expect-error -- `updateIn` keypath type should be `OrderedCollection<K> | ArrayLike<K>;
119+
updateIn({ 10: 'a' }, customArray, (v) => `${v.toUpperCase()}`)
120+
).toThrow('Cannot update within non-data-structure value in path [10]: a');
121+
});
122+
75123
it('identity with notSetValue is still identity', () => {
76124
const m = Map({ a: { b: { c: 10 } } });
77125
expect(m.updateIn(['x'], 100, (id) => id)).toEqual(m);
@@ -159,7 +207,9 @@ describe('updateIn', () => {
159207
const m = fromJS({ a: { b: { c: 10 } } });
160208
expect(() => {
161209
m.updateIn(['a', 'b', 'c', 'd'], () => 20).toJS();
162-
}).toThrow();
210+
}).toThrow(
211+
'Cannot update within non-data-structure value in path ["a","b","c"]: 10'
212+
);
163213
});
164214

165215
it('update with notSetValue when non-existing key', () => {

src/functional/updateIn.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function updateInDeeply(
4141
if (!wasNotSet && !isDataStructure(existing)) {
4242
throw new TypeError(
4343
'Cannot update within non-data-structure value in path [' +
44-
keyPath.slice(0, i).map(quoteString) +
44+
Array.from(keyPath).slice(0, i).map(quoteString) +
4545
']: ' +
4646
existing
4747
);

0 commit comments

Comments
 (0)
0