Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript 3.9 breaks getters in extendObservable #2386

Closed
JabX opened this issue Jun 28, 2020 · 6 comments
Closed

Typescript 3.9 breaks getters in extendObservable #2386

JabX opened this issue Jun 28, 2020 · 6 comments
Labels

Comments

@JabX
Copy link

JabX commented Jun 28, 2020

Typescript 3.9 introduced a sneaky breaking change regarding the way getter are emitted by setting enumerable: false instead of enumerable: true (associated PR here).

This causes extendObservable to ignore properties defined as getters in its second parameter, like that :

const obs = extendObservable({a: 2, b: 3}, { get c() { return a + b; });
obs.c // undefined (!!)

I'm a bit surprised that no one has yet reported this, it literally broke my entire app once I upgraded.

I'm not sure how this can be mitigated : how can extendObservable enumerate the properties to add if they aren't actually enumerable?

@JabX JabX added the 🐛 bug label Jun 28, 2020
@danielkcz
Copy link
Contributor

danielkcz commented Jun 28, 2020

Interesting observation. It doesn't seem we can really do much here. I see some complaint in the linked PR so hopefully, they will give it a second thought. I guess you have to stick to the previous TS till then.

@mweststrate
Copy link
Member

mweststrate commented Jun 28, 2020 via email

@JabX
Copy link
Author

JabX commented Jun 29, 2020

This is actually the only behavior that TS supports now, there is no plan to add a flag or something to control it. I ended up reverting to 3.8 for the time being.

They keep mentioning classes though in their justification (and in the existing complaints), but here I'm not using a class at all, just a plain JS object. Is the behavior really supposed to be the same here?

I forgot to mention, but I am using MobX 4 (latest), so I don't know if it also happens in 5.

If we were to switch to using Object.getOwnPropertyNames, isn't it going to break something else? Like weird inheritance-based patterns or something?

@mweststrate
Copy link
Member

I think there would be little risk in updating that, as the second argument of extendObservable is supposed to be a plain object anyway.

@mweststrate
Copy link
Member

Anybody interested in making a PR for this one on v5/4? I think the unit tests from 6 could be reused directly:

test("extendObservable can be used late and support non-enumerable getters #2386", () => {
function MyClass() {
const args = {
x: 1,
inc() {
this.x++
}
}
Object.defineProperty(args, "double", {
get() {
return this.x
},
enumerable: false
})
extendObservable(this, args)
}
const i = new MyClass()
expect(isObservableProp(i, "x")).toBe(true)
expect(isComputedProp(i, "double")).toBe(true)

@mweststrate
Copy link
Member

Fixed and released as (4/5).14.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants