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

Support Parsing Nullish Coalescing, Optional Chaining and Assertion Functions (TS 3.7) #1033

Closed
furudean opened this issue Oct 2, 2019 · 18 comments · Fixed by #1045
Closed
Labels
dependencies Issue about dependencies of the package enhancement New feature or request has pr there is a PR raised to close this package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin

Comments

@furudean
Copy link

furudean commented Oct 2, 2019

The TypeScript 3.7 beta is out.

There should be support to lint code using typescript-eslint with the new features in this version: nullish coalescing, optional chaining and assertion functions!

This post was changed from it's original state as it's pinned now ❤️

@furudean furudean added package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for maintainers to take a look labels Oct 2, 2019
@a-tarasyuk
Copy link
Contributor

@c-bandy Thanks for the report. typescript-eslint doesn't currently support the latest version (3.7.0-beta) of TypeScript. The new version was published yesterday and includes several new features. After the 3.7.0 will be released, definitely typescript-eslint will support it.

Also, typescript-eslint reports about that

WARNING: You are currently running a version of TypeScript which is not officially supported by typescript-estree.
You may find that it works just fine, or you may not.
SUPPORTED TYPESCRIPT VERSIONS: >=3.2.1 <3.7.0
YOUR TYPESCRIPT VERSION: 3.7.0-beta
Please only submit bug reports when using the officially supported version.

cc @bradzacher

@furudean
Copy link
Author

furudean commented Oct 2, 2019

@a-tarasyuk I'm aware it's not officially supported. It seemed like it was at least partially supported because I could get optional chaining (foo?.bar) to lint without any problems. I'm not very experienced in this area so I don't know if it was just coincidence or not, but thanks for your input! 🙂

@a-tarasyuk
Copy link
Contributor

a-tarasyuk commented Oct 2, 2019

@c-bandy

It seemed like it was at least partially supported because I could get optional chaining (foo?.bar) to
lint without any problems.

Based on the release notes, optional chaining? was implemented in 3.7.0-beta. :)

@narthollis
Copy link

narthollis commented Oct 2, 2019

3.7.0-beta includes both Nullish Coalescing and Optional Chaining (nullish coalescing is the next major heading after optional chaining in the release notes)

I am haply using both of these features with typescript 3.7.0-beta, except that eslint and other tools that use typescript-estree are giving errors when they run into ??.

I understand it not being implemented yet - its a new feature after all. I'll be subscribing to this issue to track happenings, Thanks for a great tool.

@furudean
Copy link
Author

furudean commented Oct 2, 2019

@a-tarasyuk That's how I knew about it to begin with, I was just surprised optional chaining worked out of the box

@bradzacher
Copy link
Member

bradzacher commented Oct 2, 2019

My dudes! You're too quick! The beta was only released yesterday.

We'll ofc be adding support for it. Because it's new syntax, we'll have to build in support to the parser for it, and also build support into the rules for it.

Optional chaining probably emits an extra prop onto an existing node - hence it's "supported" (note that it's not actually supported, it just doesn't throw an error).
Nullish coalescing, on the other hand, is a new operator that will require explicit support to not throw errors.


I'll have a look at adding support to the parser for this tonight.

Thinking about it, it'll probably be a larger piece of work to add support for this across all of the rules, but at least I can stop the parser barfing for you.


Pinning this issue to try and make sure that nobody else posts 3.7-beta issues...

@bradzacher bradzacher removed the triage Waiting for maintainers to take a look label Oct 2, 2019
@bradzacher bradzacher pinned this issue Oct 2, 2019
@bradzacher bradzacher added dependencies Issue about dependencies of the package enhancement New feature or request labels Oct 2, 2019
@bradzacher bradzacher changed the title TS 3.7 - Nullish coalescing operator does not work/is unsupported Support Nullish Coalescing and Optional Chaining (TS 3.7) Oct 2, 2019
@AlCalzone
Copy link

AlCalzone commented Oct 2, 2019

Optional chaining probably emits an extra prop onto an existing node - hence it's "supported" (note that it's not actually supported, it just doesn't throw an error).

So is this
grafik
an error in eslint or the prettier rule?

@bradzacher
Copy link
Member

uhhh - I don't actually know. It parses fine using our parser.
But the prettier plugin defers to our parser as well... so it should just work?
I'm not sure why that happens!

@bradzacher
Copy link
Member

bradzacher commented Oct 2, 2019

I used a local version of astexplorer to test this with typescript@beta.

Optional chaining:

x?.concat([]);
TS provides the following AST
{
  "pos": 0,
  "end": 15,
  "flags": 0,
  "modifierFlagsCache": 0,
  "transformFlags": 0,
  "kind": 288,
  "text": "x?.concat([]);\n",
  "bindDiagnostics": [],
  "languageVersion": 99,
  "fileName": "astExplorer.tsx",
  "languageVariant": 1,
  "isDeclarationFile": false,
  "scriptKind": 4,
  "pragmas": {},
  "referencedFiles": [],
  "typeReferenceDirectives": [],
  "libReferenceDirectives": [],
  "amdDependencies": [],
  "hasNoDefaultLib": false,
  "statements": [
    {
      "pos": 0,
      "end": 14,
      "flags": 0,
      "modifierFlagsCache": 536870912,
      "transformFlags": 0,
      "parent": "[Circular ~]",
      "kind": 225,
      "expression": {
        "pos": 0,
        "end": 13,
        "flags": 32,
        "modifierFlagsCache": 0,
        "transformFlags": 0,
        "parent": "[Circular ~.statements.0]",
        "kind": 195,
        "expression": {
          "pos": 0,
          "end": 9,
          "flags": 32,
          "modifierFlagsCache": 0,
          "transformFlags": 0,
          "parent": "[Circular ~.statements.0.expression]",
          "kind": 193, // PropertyAccessExpression
          "expression": {
            "pos": 0,
            "end": 1,
            "flags": 0,
            "modifierFlagsCache": 0,
            "transformFlags": 0,
            "parent": "[Circular ~.statements.0.expression.expression]",
            "kind": 75,
            "escapedText": "x"
          },
//////////// THE NEW "QuestionDotToken" ////////////
          "questionDotToken": {
            "pos": 1,
            "end": 3,
            "flags": 0,
            "modifierFlagsCache": 0,
            "transformFlags": 0,
            "parent": "[Circular ~.statements.0.expression.expression]",
            "kind": 28 // QuestionDotToken
          },
////////////////////////////////////////////////////
          "name": {
            "pos": 3,
            "end": 9,
            "flags": 0,
            "modifierFlagsCache": 0,
            "transformFlags": 0,
            "parent": "[Circular ~.statements.0.expression.expression]",
            "kind": 75,
            "escapedText": "concat"
          }
        },
        "arguments": [
          {
            "pos": 10,
            "end": 12,
            "flags": 0,
            "modifierFlagsCache": 0,
            "transformFlags": 0,
            "parent": "[Circular ~.statements.0.expression]",
            "kind": 191,
            "elements": []
          }
        ]
      }
    }
  ],
  "endOfFileToken": {
    "pos": 14,
    "end": 15,
    "flags": 0,
    "modifierFlagsCache": 0,
    "transformFlags": 0,
    "parent": "[Circular ~]",
    "kind": 1
  },
  "nodeCount": 9,
  "identifierCount": 2,
  "identifiers": {},
  "parseDiagnostics": [],
  "path": "astExplorer.tsx",
  "resolvedPath": "astExplorer.tsx",
  "originalFileName": "astExplorer.tsx",
  "imports": [],
  "moduleAugmentations": [],
  "ambientModuleNames": []
}

Nullish coalescing

x ?? y
TS provides the following AST
{
  "pos": 0,
  "end": 8,
  "flags": 0,
  "modifierFlagsCache": 0,
  "transformFlags": 0,
  "kind": 288,
  "text": "x ?? y;\n",
  "bindDiagnostics": [],
  "languageVersion": 99,
  "fileName": "astExplorer.tsx",
  "languageVariant": 1,
  "isDeclarationFile": false,
  "scriptKind": 4,
  "pragmas": {},
  "referencedFiles": [],
  "typeReferenceDirectives": [],
  "libReferenceDirectives": [],
  "amdDependencies": [],
  "hasNoDefaultLib": false,
  "statements": [
    {
      "pos": 0,
      "end": 7,
      "flags": 0,
      "modifierFlagsCache": 536870912,
      "transformFlags": 0,
      "parent": "[Circular ~]",
      "kind": 225,
      "expression": {
        "pos": 0,
        "end": 6,
        "flags": 0,
        "modifierFlagsCache": 0,
        "transformFlags": 0,
        "parent": "[Circular ~.statements.0]",
        "kind": 208, // BinaryExpression
        "left": {
          "pos": 0,
          "end": 1,
          "flags": 0,
          "modifierFlagsCache": 0,
          "transformFlags": 0,
          "parent": "[Circular ~.statements.0.expression]",
          "kind": 75,
          "escapedText": "x"
        },
//////////// THE NEW "QuestionQuestionToken" ////////////
        "operatorToken": {
          "pos": 1,
          "end": 4,
          "flags": 0,
          "modifierFlagsCache": 0,
          "transformFlags": 0,
          "parent": "[Circular ~.statements.0.expression]",
          "kind": 60 // QuestionQuestionToken
        },
/////////////////////////////////////////////////////////
        "right": {
          "pos": 4,
          "end": 6,
          "flags": 0,
          "modifierFlagsCache": 0,
          "transformFlags": 0,
          "parent": "[Circular ~.statements.0.expression]",
          "kind": 75,
          "escapedText": "y"
        }
      }
    }
  ],
  "endOfFileToken": {
    "pos": 7,
    "end": 8,
    "flags": 0,
    "modifierFlagsCache": 0,
    "transformFlags": 0,
    "parent": "[Circular ~]",
    "kind": 1
  },
  "nodeCount": 7,
  "identifierCount": 2,
  "identifiers": {},
  "parseDiagnostics": [],
  "path": "astExplorer.tsx",
  "resolvedPath": "astExplorer.tsx",
  "originalFileName": "astExplorer.tsx",
  "imports": [],
  "moduleAugmentations": [],
  "ambientModuleNames": []
}

Assertion function

function assert(condition): asserts condition {}
TS provides the following AST
{
  "pos": 0,
  "end": 49,
  "flags": 0,
  "modifierFlagsCache": 0,
  "transformFlags": 0,
  "kind": 288,
  "text": "function assert(condition): asserts condition {}\n",
  "bindDiagnostics": [],
  "languageVersion": 99,
  "fileName": "astExplorer.tsx",
  "languageVariant": 1,
  "isDeclarationFile": false,
  "scriptKind": 4,
  "pragmas": {},
  "referencedFiles": [],
  "typeReferenceDirectives": [],
  "libReferenceDirectives": [],
  "amdDependencies": [],
  "hasNoDefaultLib": false,
  "statements": [
    {
      "pos": 0,
      "end": 48,
      "flags": 0,
      "modifierFlagsCache": 536870912,
      "transformFlags": 0,
      "parent": "[Circular ~]",
      "kind": 243,
      "name": {
        "pos": 8,
        "end": 15,
        "flags": 0,
        "modifierFlagsCache": 0,
        "transformFlags": 0,
        "parent": "[Circular ~.statements.0]",
        "kind": 75,
        "escapedText": "assert"
      },
      "parameters": [
        {
          "pos": 16,
          "end": 25,
          "flags": 0,
          "modifierFlagsCache": 0,
          "transformFlags": 0,
          "parent": "[Circular ~.statements.0]",
          "kind": 155,
          "name": {
            "pos": 16,
            "end": 25,
            "flags": 0,
            "modifierFlagsCache": 0,
            "transformFlags": 0,
            "parent": "[Circular ~.statements.0.parameters.0]",
            "kind": 75,
            "escapedText": "condition"
          }
        }
      ],
      "type": {
        "pos": 27,
        "end": 45,
        "flags": 0,
        "modifierFlagsCache": 0,
        "transformFlags": 0,
        "parent": "[Circular ~.statements.0]",
        "kind": 167, // TypePredicate
//////////// THE NEW "AssertsKeyword" ////////////
        "assertsModifier": {
          "pos": 27,
          "end": 35,
          "flags": 0,
          "modifierFlagsCache": 0,
          "transformFlags": 0,
          "parent": "[Circular ~.statements.0.type]",
          "kind": 123
        },
//////////////////////////////////////////////////
        "parameterName": {
          "pos": 35,
          "end": 45,
          "flags": 0,
          "modifierFlagsCache": 0,
          "transformFlags": 0,
          "parent": "[Circular ~.statements.0.type]",
          "kind": 75,
          "escapedText": "condition"
        }
      },
      "body": {
        "pos": 45,
        "end": 48,
        "flags": 0,
        "modifierFlagsCache": 0,
        "transformFlags": 0,
        "parent": "[Circular ~.statements.0]",
        "kind": 222,
        "statements": []
      }
    }
  ],
  "endOfFileToken": {
    "pos": 48,
    "end": 49,
    "flags": 0,
    "modifierFlagsCache": 0,
    "transformFlags": 0,
    "parent": "[Circular ~]",
    "kind": 1
  },
  "nodeCount": 11,
  "identifierCount": 4,
  "identifiers": {},
  "parseDiagnostics": [],
  "path": "astExplorer.tsx",
  "resolvedPath": "astExplorer.tsx",
  "originalFileName": "astExplorer.tsx",
  "imports": [],
  "moduleAugmentations": [],
  "ambientModuleNames": []
}

@bradzacher bradzacher changed the title Support Nullish Coalescing and Optional Chaining (TS 3.7) Support Nullish Coalescing, Optional Chaining and Assertion Functions (TS 3.7) Oct 2, 2019
@bytenik
Copy link

bytenik commented Oct 3, 2019

Thinking about it, it'll probably be a larger piece of work to add support for this across all of the rules, but at least I can stop the parser barfing for you.

Yes, "anti-barfing support" would be fantastic. 😎 Real support is less critical than being able to continue to use existing eslint functionality while this sort of thing gets worked out. Thanks a bunch!

@narthollis
Copy link

My dudes! You're too quick! The beta was only released yesterday.

This is true - I was mostly just looking for a tracking item - apologies for the noise.

Thinking about it, it'll probably be a larger piece of work to add support for this across all of the rules, but at least I can stop the parser barfing for you.

This would be fantastic - being able to keep using tools even without direct support would great.

@bradzacher bradzacher added the has pr there is a PR raised to close this label Oct 4, 2019
@bradzacher bradzacher changed the title Support Nullish Coalescing, Optional Chaining and Assertion Functions (TS 3.7) Support Parsing Nullish Coalescing, Optional Chaining and Assertion Functions (TS 3.7) Oct 8, 2019
@bradzacher
Copy link
Member

Just updating - this issue is specifically for parsing.
For supporting the syntax in rules, see #1051 and #1052

@bradzacher
Copy link
Member

Official support has been released!

Note that there shouldn't have been any parser errors on these, the errors people were getting were because prettier hard errors on things it doesn't support.

If you want to track progress in prettier, see
prettier/prettier#6595
prettier/prettier#6609

@RichieRunner
Copy link

Official support has been released!

Note that there shouldn't have been any parser errors on these, the errors people were getting were because prettier hard errors on things it doesn't support.

If you want to track progress in prettier, see
prettier/prettier#6595
prettier/prettier#6609

Which release is this in?

@bradzacher
Copy link
Member

https://github.com/typescript-eslint/typescript-eslint/blob/master/CHANGELOG.md

@damiangreen
Copy link

I've been struggling to get eslint to understand typescript's 3.7 features, especially optional chaining. I have parser: '@typescript-eslint/parser',
'@typescript-eslint', in my plugins.

however I get undef errors when running eslint.
Would be amazing if someone can shed some light on what piece of the puzzle i'm missing

@bradzacher
Copy link
Member

If you're looking for support in the rules, see the issues linked in
#1033 (comment)

As mentioned in the title, and in the comment above - this issue is specifically about parsing support (i.e. making sure that an AST is produced so that eslint won't crash out on the new syntax).

There are a number of issues with some of the base rules due to how eslint works.
These are logged and PRs have been raised. #1090 #1104 #1116 #1138

For everyone:
If you'd like to see wider support for the new syntax in the rules, feel free to hop in and raise some PRs.
We are a community run project, so we rely on community contributions to help us move fast.

@kalbert312
Copy link

A note on the ESLint parsing error: Expression expected... if your IDE is running ESLint in the background and you upgrade your packages you need to restart the IDE or the ESLint process. Source: also ran into this.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
dependencies Issue about dependencies of the package enhancement New feature or request has pr there is a PR raised to close this package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants