Closed
Description
Description
The updateIn
function does call coerceKeyPath
on the keyPath.
The coerceKeyPath does check if the keyPath is an "ArrayLike". If true, the value is kept.
In the updateIn, if the keyPath does not match the object, then we call this line, that does construct its error message with keyPath.slice(0, i)
, but .slice
might not exist on a custom ArrayLike method.
Here is the implementation of isArrayLike
: https://github.com/immutable-js/immutable-js/blob/main/src/utils/isArrayLike.ts
Reproductible example
Define the custom array
class CustomArrayLike<T> implements ArrayLike<T> {
readonly length: number;
readonly [n: number]: T;
constructor(length: number) {
this.length = length;
for (let i = 0; i < length; i++) {
this[i] = undefined as any;
}
}
// Define other methods if needed, but do not include the `slice` method
// For example, you can define a method to set values
set(index: number, value: T): void {
if (index >= 0 && index < this.length) {
this[index] = value;
} else {
throw new RangeError('Index out of bounds');
}
}
// Define a method to get values
get(index: number): T {
if (index >= 0 && index < this.length) {
return this[index];
} else {
throw new RangeError('Index out of bounds');
}
}
}
Code that throws
// create an ArrayLike
const customArray = new CustomArrayLike<number>(2);
customArray.set(0, 10);
customArray.set(1, 20);
// code that works perfectly
Immutable.updateIn({ 10 :{ 20 : 'a' }}, customArray2, (v) => `${v.toUpperCase()}`)
// does output { 10 :{ 20 : 'A' }}
Immutable.updateIn({ 10 : 'a' }, customArray2, (v) => `${v.toUpperCase()}`)
// does throw Uncaught TypeError: keyPath.slice is not a function
Metadata
Metadata
Assignees
Labels
No labels