-
Notifications
You must be signed in to change notification settings - Fork 12.8k
ESNext emits optional class members #47350
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
Comments
I believe that this is intended. If you want to signal that this was truly not present (i.e. "this thing will potentially not be set"), then you'll need to use the class C {
declare x?: number;
} |
@DanielRosenwasser I think that's a good enough workaround in practice. That said, it means |
Sounds like this is possibly a bug in |
Specifically, under both class C {
x?: number;
y = 3;
}
function foo(obj: C) {
if ("x" in obj) {
obj.x.valueOf();
}
} |
Isnβt this for consistency w.r.t. [[Define]] vs. [[Set]] semantics for fields? [[Define]] semantics require the field to be declared in the class body, or Itβd be confusing, IMO, to have some properties using [[Define]] and some using [[Set]] depending on whether they were optional or not. |
It's more about the fact that property declarations unconditionally add a property even if there's no initializer. If you want the type system to correctly encode whether something is possibly-missing vs. possibly- |
Right, but my point was that if |
The discussion is so cluttered for such a clear cut bug π class A { foo?: 0; }
// target: "ES2020" | new A() is { foo?: 0 } β
class A {}
// target: "ESNext" | new A() is { foo: 0 | undefined } β
class A { foo; } |
Bumped into this one today. Extending @pushkine example, if I have a decorator to define a property with a getter, that won't work in Example: class Foo {}
class C {
@dependency() foo: Foo;
}
function dependency() {
return function(target, property) {
Object.defineProperty(target, property, {
get() {
return new Foo();
}
});
}
}
// target: "ES2020" β
class C {}
new C().foo instanceof Foo === true;
// target: "ESNext" β
//foo is `undefined` because it is a property in every instance of C, overriding the getter from C.prototype
class C { foo; }
new C().foo instanceof Foo === false; |
Bug Report
π Search Terms
optional class members
π Version & Regression Information
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
x
is emitted as a class member, even though it was optional.This feels wrong, but to make a stronger point consider
--exactOptionalPropertyTypes
.With this compiler option, we should have the typing invariant
!("x" in c) || typeof c.x == "number"
; but with this emit, a new instance has the opposite"x" in c && typeof c.x == "undefined"
.π Expected behavior
Optional members should probably not be emitted:
I am not sure / have not thought about what the implications with respect to
useDefineForClassFields
semantics are.The text was updated successfully, but these errors were encountered: