diff --git a/.changeset/hip-seals-kiss.md b/.changeset/hip-seals-kiss.md new file mode 100644 index 000000000..9d0ea32e8 --- /dev/null +++ b/.changeset/hip-seals-kiss.md @@ -0,0 +1,5 @@ +--- +"mobx": patch +--- + +Fix regression from #4639 where isComputedProp returned false for lazy @computed properties before first read diff --git a/packages/mobx/__tests__/decorators_20223/stage3-decorators.ts b/packages/mobx/__tests__/decorators_20223/stage3-decorators.ts index 00bc79b2b..39dc348e8 100644 --- a/packages/mobx/__tests__/decorators_20223/stage3-decorators.ts +++ b/packages/mobx/__tests__/decorators_20223/stage3-decorators.ts @@ -22,7 +22,8 @@ import { IAtom, createAtom, runInAction, - makeObservable + makeObservable, + isComputedProp } from "../../src/mobx" import { $mobx, type ObservableArrayAdministration } from "../../src/internal" import * as mobx from "../../src/mobx" @@ -1191,6 +1192,19 @@ test("4616 - @computed decorator should be lazy", () => { expect(computeCount).toBe(0) }) +test("4616 - isComputedProp reports lazy @computed before first read", () => { + class Order { + @computed + get total() { + return 3 + } + } + + const o = new Order() + + t.equal(isComputedProp(o, "total"), true) +}) + test("4616 - observe on @computed before first read materialises it", () => { class Order { @observable accessor price: number = 3 diff --git a/packages/mobx/src/api/iscomputed.ts b/packages/mobx/src/api/iscomputed.ts index 692da37e3..2a7d07e4c 100644 --- a/packages/mobx/src/api/iscomputed.ts +++ b/packages/mobx/src/api/iscomputed.ts @@ -7,7 +7,11 @@ export function _isComputed(value, property?: PropertyKey): boolean { if (isObservableObject(value) === false) { return false } - if (!value[$mobx].values_.has(property)) { + const adm = value[$mobx] + if (adm.lazyComputedKeys_?.has(property)) { + return true + } + if (!adm.values_.has(property)) { return false } const atom = getAtom(value, property)