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

Emit grammar error on quoted constructors and class fields named “constructor” #31119

Merged
merged 7 commits into from May 1, 2019

Conversation

andrewbranch
Copy link
Member

Phase 1 of #31020

This is an inherently awkward error message to give. Basically the message tells you that “This syntax compiles in every version of TypeScript except this one,” which isn’t particularly actionable. So I decided to explain how you can get either a constructor or a method in a backward-compatible and future-proof way:

In the meantime, consider using 'constructor()' to write a constructor, or '"constructor"' to write a method.

On the one hand, this makes the message actionable, no matter what your intent. On the other hand, what I’d rather say is more like “oh no please don’t define a method named constructor 😭”

@andrewbranch andrewbranch changed the title Emit error Emit grammar error on quoted constructors Apr 25, 2019
@RyanCavanaugh
Copy link
Member

This is the kind of thing it's nice to seed a StackOverflow Q/A for

},
"Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '[\"constructor\"]()' to write a method.": {
"category": "Error",
"code": 96000
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use a normal code here; it's fine to introduce a gap in the sequence later

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused about why 18004 was way down here. Now I see that's the latest of an earlier sequence.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to 18005

@weswigham
Copy link
Member

We also need to consider emittin an error for properties named "constructor". In ES2018+, class C { "constructor"; } will throw with Uncaught SyntaxError: Classes may not have a field named 'constructor' 😦

@andrewbranch
Copy link
Member Author

class C {
  "constructor" = 3; // Error in ES2018+
  ["constructor"] = 3; // No error and has exactly the same effect
}

I understand why this is, but it makes me very sad

@andrewbranch
Copy link
Member Author

@weswigham should this trigger an error

  1. if your script target is >= ES2018, because that's when node will give you an error
  2. if your script target is >= ES2015, because that's when we emit code that will give you an error if you run it in latest node versions
  3. all the time, because if JavaScript made something illegal going forward because it has confusing semantics, TypeScript should probably do the same

(I don't think option 1 is a real option, I just wanted to lay out all the arguments)

@weswigham
Copy link
Member

if your script target is >= ES2015, because that's when we emit code that will give you an error if you run it in latest node versions

In the case of the constructor property, doesn't it only cause an error when we don't transform it? Isn't our downlevel to an assignment within the constructor perfectly serviceable (at least until we adopt define semantics)?

@weswigham
Copy link
Member

Probably 3 though, I think. At least that's the stance we've usually taken. If we can keep backwards compatible emit/checking behavior for it so it can be @ts-ignore'd in older codebases, all the better.

@andrewbranch
Copy link
Member Author

In the case of the constructor property, doesn't it only cause an error when we don't transform it? Isn't our downlevel to an assignment within the constructor perfectly serviceable

Oh right, I was only thinking about when we start emitting classes. Assigning in the constructor still works. [Verifies that assertion] ... [Is not a liar]

I agree though, seems reasonable to disallow this invariantly regardless. Chances are, if someone is currently doing this, they’ll get hit by it eventually. May as well be sooner rather than later, and they’re better off catching it at compile time than at runtime.

@andrewbranch andrewbranch changed the title Emit grammar error on quoted constructors Emit grammar error on quoted constructors and class fields named “constructor” Apr 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants