tree-sitter / tree-sitter-typescript

TypeScript grammar for tree-sitter
MIT License
335 stars 104 forks source link

The parser allows optional rest params, but TypeScript does not #222

Closed kevinbarabash closed 1 year ago

kevinbarabash commented 1 year ago

The following piece of code is parsed without error by tree-sitter-typescript.

const foo = (a: number, ...b?: number[]): void => {}

Here's a link to the TypeScript Playground showing that rest params cannot be marked as optional: https://www.typescriptlang.org/play?#code/MYewdgzgLgBAZiEMC8MAUBDAXDMBXAWwCMBTAJwBoYA6Wogfh32PIG0BdAShwDcQBLACYoAfDADeAXwBQMOUA

[program](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [1, 0]
  [lexical_declaration](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [0, 52]
    [variable_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [0, 6] - [0, 52]
      name: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [0, 6] - [0, 9]
      value: [arrow_function](https://tree-sitter.github.io/tree-sitter/playground#) [0, 12] - [0, 52]
        parameters: [formal_parameters](https://tree-sitter.github.io/tree-sitter/playground#) [0, 12] - [0, 40]
          [required_parameter](https://tree-sitter.github.io/tree-sitter/playground#) [0, 13] - [0, 22]
            pattern: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [0, 13] - [0, 14]
            type: [type_annotation](https://tree-sitter.github.io/tree-sitter/playground#) [0, 14] - [0, 22]
              [predefined_type](https://tree-sitter.github.io/tree-sitter/playground#) [0, 16] - [0, 22]
          [optional_parameter](https://tree-sitter.github.io/tree-sitter/playground#) [0, 24] - [0, 39]
            pattern: [rest_pattern](https://tree-sitter.github.io/tree-sitter/playground#) [0, 24] - [0, 28]
              [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [0, 27] - [0, 28]
            type: [type_annotation](https://tree-sitter.github.io/tree-sitter/playground#) [0, 29] - [0, 39]
              [array_type](https://tree-sitter.github.io/tree-sitter/playground#) [0, 31] - [0, 39]
                [predefined_type](https://tree-sitter.github.io/tree-sitter/playground#) [0, 31] - [0, 37]
        return_type: [type_annotation](https://tree-sitter.github.io/tree-sitter/playground#) [0, 40] - [0, 46]
          [predefined_type](https://tree-sitter.github.io/tree-sitter/playground#) [0, 42] - [0, 46]
        body: [statement_block](https://tree-sitter.github.io/tree-sitter/playground#) [0, 50] - [0, 52]

I was expecting there to be an ERROR node after the rest_parameter and the enclosing optional_parameter to be a required_parameter.

kevinbarabash commented 1 year ago

I thought about this a bit more and it doesn't make sense for the tree-sitter parser to do this check since it's a semantic issue. Sorry for the noise.

hendrikvanantwerpen commented 1 year ago

No problem @kevinbarabash! This one is on the edge, I'd say. Because the rest pattern cannot appear anywhere with the optional (or probably any) annotation, it would be fine to rule it out in the grammar.