From 01e6a3e5b006721cde028bf86ff10d71e2eea5c4 Mon Sep 17 00:00:00 2001 From: takeramagan Date: Sun, 7 Jan 2024 01:38:44 -0500 Subject: [PATCH] fix #2017 reconcile fails to replace nested array with object --- packages/solid/store/src/modifiers.ts | 9 ++++++++- packages/solid/store/test/modifiers.spec.ts | 22 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/solid/store/src/modifiers.ts b/packages/solid/store/src/modifiers.ts index 8c33d496c..420ba1259 100644 --- a/packages/solid/store/src/modifiers.ts +++ b/packages/solid/store/src/modifiers.ts @@ -14,9 +14,16 @@ function applyState( merge: boolean | undefined, key: string | null ) { - const previous = parent[property]; + let previous = parent[property]; if (target === previous) return; const isArray = Array.isArray(target); + if (Array.isArray(previous) && !isArray) { + parent[property] = {}; + } else if (!Array.isArray(previous) && isArray) { + parent[property] = []; + } + + previous = parent[property]; if ( property !== $ROOT && (!isWrappable(target) || diff --git a/packages/solid/store/test/modifiers.spec.ts b/packages/solid/store/test/modifiers.spec.ts index 2e85b00e3..79ff9a24b 100644 --- a/packages/solid/store/test/modifiers.spec.ts +++ b/packages/solid/store/test/modifiers.spec.ts @@ -134,6 +134,28 @@ describe("setState with reconcile", () => { expect(store.id).toBe(undefined); expect(store.value).toBe(undefined); }); + + test("Reconcile overwirte an object with an array", () => { + const [store, setStore] = createStore<{ value: {} | [] }>({ + value: { a: { b: 1 } } + }); + + setStore(reconcile({ value: { c: [1, 2, 3] } })); + expect(store.value).toEqual({ c: [1, 2, 3] }); + }); + + test("Reconcile overwirte an array with an object", () => { + const [store, setStore] = createStore<{ value: {} | [] }>({ + value: [1, 2, 3] + }); + setStore(reconcile({ value: { name: "John" } })); + expect(Array.isArray(store.value)).toBeFalsy(); + expect(store.value).toEqual({ name: "John" }); + setStore(reconcile({ value: [1, 2, 3] })); + expect(store.value).toEqual([1, 2, 3]); + setStore(reconcile({ value: { q: "aa" } })); + expect(store.value).toEqual({ q: "aa" }); + }); }); describe("setState with produce", () => {