From bb40c3610d69003eafd1e6504137f061cef164ff Mon Sep 17 00:00:00 2001 From: Stepan Burguchev Date: Sun, 2 Aug 2020 12:21:45 +0200 Subject: [PATCH] fix: use Array.prototype.slice() for copying arrays. Fixes #650 --- __tests__/regressions.js | 18 ++++++++++++++++++ src/utils/common.ts | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/__tests__/regressions.js b/__tests__/regressions.js index a8e65c71..9ae9138b 100644 --- a/__tests__/regressions.js +++ b/__tests__/regressions.js @@ -140,5 +140,23 @@ function runBaseTest(name, useProxies, autoFreeze, useListener) { }) expect(result).toEqual(new Set()) }) + + test("#650 - changes with overridden arr.slice() fail", () => { + const data = { + foo: [ + { + isActive: false + } + ] + } + // That's roughly what seamless-immutable does + data.foo.slice = (...args) => + Object.freeze(Array.prototype.slice.call(data.foo, ...args)) + + const newData = produce(data, draft => { + draft.foo[0].isActive = true + }) + expect(newData.foo[0].isActive).toBe(true) + }) }) } diff --git a/src/utils/common.ts b/src/utils/common.ts index ab3d2623..67980747 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -154,7 +154,7 @@ export function latest(state: ImmerState): any { /*#__PURE__*/ export function shallowCopy(base: any) { - if (Array.isArray(base)) return base.slice() + if (Array.isArray(base)) return Array.prototype.slice.call(base) const descriptors = getOwnPropertyDescriptors(base) delete descriptors[DRAFT_STATE as any] let keys = ownKeys(descriptors)