Skip to content

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

Closed
@evanw

Description

@evanw

πŸ”Ž 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.
    

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptDomain: DecoratorsThe issue relates to the decorator syntaxFix AvailableA PR has been opened for this issueRescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions