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

TS 5.0 decorators don't follow the DecoratorCallExpression grammar #55336

Closed
evanw opened this issue Aug 11, 2023 · 2 comments · Fixed by #57749
Closed

TS 5.0 decorators don't follow the DecoratorCallExpression grammar #55336

evanw opened this issue Aug 11, 2023 · 2 comments · Fixed by #57749
Assignees
Labels
Bug A bug in TypeScript Domain: Decorators The issue relates to the decorator syntax Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@evanw
Copy link
Contributor

evanw commented Aug 11, 2023

🔎 Search Terms

DecoratorCallExpression

🕗 Version & Regression Information

  • This issue is specific to TypeScript 5.0+ decorators (not experimental decorators)

⏯ Playground Link

https://www.typescriptlang.org/play?target=99&ts=5.1.6#code/CYUwxgNghgTiAEEQBd4A8Bc8AUBKeAvAHzwDe8AnlnoSdpvFAHYUA0lWzF+xjL8AXwCwAKAACaPADoKeUZCgBnRfABmAe3VlhIoA

💻 Code

declare let x: () => { y: () => (x: any, y: any) => any }
@x().y()
class foo {}

🙁 Actual behavior

TypeScript allows this invalid syntax without any errors.

🙂 Expected behavior

Here's the grammar (taken from the spec linked in the proposal):

Decorator[Yield, Await] :
    @ DecoratorMemberExpression[?Yield, ?Await]
    @ DecoratorParenthesizedExpression[?Yield, ?Await]
    @ DecoratorCallExpression[?Yield, ?Await]

DecoratorMemberExpression[Yield, Await] :
    IdentifierReference[?Yield, ?Await]
    DecoratorMemberExpression[?Yield, ?Await] . IdentifierName
    DecoratorMemberExpression[?Yield, ?Await] . PrivateIdentifier

DecoratorParenthesizedExpression[Yield, Await] :
    ( Expression[+In, ?Yield, ?Await] )

DecoratorCallExpression[Yield, Await] :
    DecoratorMemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

My reading of this grammar is that TypeScript should only be allowing a single Arguments production at the end of the decorator. So I believe TypeScript should consider this example to be a syntax error. Here's what other decorator parsers do:

  • Babel:

    /repl.ts: Leading decorators must be attached to a class declaration. (2:4)
    
      1 | declare let x: () => { y: () => (x: any, y: any) => any }
    > 2 | @x().y()
        |     ^
      3 | class foo {}
      4 |
    
  • esbuild:

    ✘ [ERROR] Expected "class" after decorator but found "."
    
        <stdin>:2:4:
          2 │ @x().y()
            ╵     ^
    
      The preceding decorator is here:
    
        <stdin>:2:0:
          2 │ @x().y()
            ╵ ^
    
      Decorators can only be used with class declarations.
    
@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Aug 11, 2023
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 5.3.0 milestone Aug 11, 2023
@rektide
Copy link

rektide commented Aug 31, 2023

Part of me wants to push to get the spec updated to allow more complex/arbitrary expressions. Nice spotting this.

@trusktr
Copy link
Contributor

trusktr commented Sep 23, 2023

I've been wondering if there should have been a new option called --standard-decorators (standardDecorators) that defaults to false due to small things still fluctuating (whether there or here), then eventually defaulting to true once things settle.

@RyanCavanaugh RyanCavanaugh added the Rescheduled This issue was previously scheduled to an earlier milestone label Mar 4, 2024
@typescript-bot typescript-bot added the Fix Available A PR has been opened for this issue label Mar 12, 2024
@rbuckton rbuckton added Bug A bug in TypeScript Domain: Decorators The issue relates to the decorator syntax and removed Needs Investigation This issue needs a team member to investigate its status. Fix Available A PR has been opened for this issue labels Mar 12, 2024
@typescript-bot typescript-bot added the Fix Available A PR has been opened for this issue label Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Domain: Decorators The issue relates to the decorator syntax Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone
6 participants