diff --git a/packages/solid/store/src/mutable.ts b/packages/solid/store/src/mutable.ts index 63e92b93..f88c8501 100644 --- a/packages/solid/store/src/mutable.ts +++ b/packages/solid/store/src/mutable.ts @@ -94,19 +94,35 @@ function wrap(value: T): T { Object.defineProperty(value, $PROXY, { value: (p = new Proxy(value, proxyTraps)) }); const keys = Object.keys(value), desc = Object.getOwnPropertyDescriptors(value); + + const proto = Object.getPrototypeOf(value); + const isClass = + value !== null && + typeof value === "object" && + !Array.isArray(value) && + proto !== Object.prototype; + if (isClass) { + const descriptors = Object.getOwnPropertyDescriptors(proto); + keys.push(...Object.keys(descriptors)); + Object.assign(desc, descriptors); + } + for (let i = 0, l = keys.length; i < l; i++) { const prop = keys[i]; + if (isClass && prop === "constructor") continue; if (desc[prop].get) { const get = desc[prop].get!.bind(p); Object.defineProperty(value, prop, { - get + get, + configurable: true }); } if (desc[prop].set) { const og = desc[prop].set!, set = (v: T[keyof T]) => batch(() => og.call(p, v)); Object.defineProperty(value, prop, { - set + set, + configurable: true }); } } diff --git a/packages/solid/store/test/mutableWithClass.spec.tsx b/packages/solid/store/test/mutableWithClass.spec.tsx new file mode 100644 index 00000000..8f188de5 --- /dev/null +++ b/packages/solid/store/test/mutableWithClass.spec.tsx @@ -0,0 +1,55 @@ +/** + * @jsxImportSource solid-js + * @vitest-environment jsdom + */ +import { createMutable } from "../src"; +import { render } from "../../web"; + +describe("Class Operator test", () => { + test("read and set class", () => { + let ref: any; + class D { + f = 1; + get e() { + return this.f * 4; + } + } + class A { + a = 1; + get b() { + return this.a * 4; + } + child = new D(); + } + let m: any; + function Test() { + m = createMutable(new A()); + m.a++; + m.child.f++; + + return ( + + ); + } + const div = document.createElement("div"); + + render(Test, div); + expect(m.b).toBe(8); + expect(m.child.e).toBe(8); + ref.$$click(); + expect(m.b).toBe(12); + expect(m.child.e).toBe(12); + ref.$$click(); + expect(m.b).toBe(16); + expect(m.child.e).toBe(16); + }); +});