typescript-eslint / typescript-eslint

:sparkles: Monorepo for all the tooling which enables ESLint to support TypeScript
https://typescript-eslint.io
Other
14.99k stars 2.69k forks source link

Parsing error: The keyword 'export' is reserved #1464

Closed flisboac closed 4 years ago

flisboac commented 4 years ago

What code were you trying to parse?

I'm trying to use typescript-eslint, and I followed the Getting Started page. Unfortunately, I'm having problems to make the parser identify very basic TypeScript/JS keywords, like export.

Please see https://github.com/flisboac/ts-promise-scheduler for the project in question. The error is:

./ts-promise-scheduler/src/index.ts
  1:1  error  Parsing error: The keyword 'export' is reserved

✖ 1 problem (1 error, 0 warnings)

My .eslint.js is configured as such:

module.exports = {
    root: true,
    parser: '@typescript-eslint/parser',
    plugins: [
        '@typescript-eslint',
    ],
    extends: [
        'eslint:recommended',
        'plugin:@typescript-eslint/eslint-recommended',
        'plugin:@typescript-eslint/recommended',
    ],
    parserOptions: {
        tsconfigRootDir: "./",
        project: "tsconfig.module.json",
    },
};

And here are the first lines of the affected file

export enum JobStatus {
    PENDING,
    RUNNING,
    RESOLVED,
    REJECTED,
    CANCELED,
};

// ...

What did you expect to happen?

To accept export as a keyword, as per named/default export in TypeScript and the ES6+ standards, in the context of exporting declarations.

What actually happened?

export seems to be identified as a reserved name, regardless of context. Parsing fails.

Versions

Disclaimer:I'm using yarn.

package version
@typescript-eslint/parser 2.16.0
TypeScript 3.7.4
ESLint 6.8.0
node 12.13.0
npm 6.12.0
yarn 1.21.1

Output ofyarn versions`:

yarn versions v1.21.1
{
  yarn: '1.21.1',
  'ts-promise-scheduler': '1.0.0',
  node: '12.13.0',
  v8: '7.7.299.13-node.12',
  uv: '1.32.0',
  zlib: '1.2.11',
  brotli: '1.0.7',
  ares: '1.15.0',
  modules: '72',
  nghttp2: '1.39.2',
  napi: '5',
  llhttp: '1.1.4',
  http_parser: '2.8.0',
  openssl: '1.1.1d',
  cldr: '35.1',
  icu: '64.2',
  tz: '2019a',
  unicode: '12.1'
}

Output of yarn list:

yarn list v1.21.1
├─ @babel/code-frame@7.8.3
│  └─ @babel/highlight@^7.8.3
├─ @babel/highlight@7.8.3
│  ├─ chalk@^2.0.0
│  ├─ esutils@^2.0.2
│  └─ js-tokens@^4.0.0
├─ @types/eslint-visitor-keys@1.0.0
├─ @types/json-schema@7.0.4
├─ @typescript-eslint/eslint-plugin@2.16.0
│  ├─ @typescript-eslint/experimental-utils@2.16.0
│  ├─ eslint-utils@^1.4.3
│  ├─ functional-red-black-tree@^1.0.1
│  ├─ regexpp@^3.0.0
│  ├─ regexpp@3.0.0
│  └─ tsutils@^3.17.1
├─ @typescript-eslint/experimental-utils@2.16.0
│  ├─ @types/json-schema@^7.0.3
│  ├─ @typescript-eslint/typescript-estree@2.16.0
│  └─ eslint-scope@^5.0.0
├─ @typescript-eslint/parser@2.16.0
│  ├─ @types/eslint-visitor-keys@^1.0.0
│  ├─ @typescript-eslint/experimental-utils@2.16.0
│  ├─ @typescript-eslint/typescript-estree@2.16.0
│  └─ eslint-visitor-keys@^1.1.0
├─ @typescript-eslint/typescript-estree@2.16.0
│  ├─ debug@^4.1.1
│  ├─ eslint-visitor-keys@^1.1.0
│  ├─ glob@^7.1.6
│  ├─ is-glob@^4.0.1
│  ├─ lodash@^4.17.15
│  ├─ semver@^6.3.0
│  └─ tsutils@^3.17.1
├─ acorn-jsx@5.1.0
├─ acorn@7.1.0
├─ ajv@6.10.2
│  ├─ fast-deep-equal@^2.0.1
│  ├─ fast-json-stable-stringify@^2.0.0
│  ├─ json-schema-traverse@^0.4.1
│  └─ uri-js@^4.2.2
├─ ansi-escapes@4.3.0
│  └─ type-fest@^0.8.1
├─ ansi-regex@4.1.0
├─ ansi-styles@3.2.1
│  └─ color-convert@^1.9.0
├─ argparse@1.0.10
│  └─ sprintf-js@~1.0.2
├─ astral-regex@1.0.0
├─ balanced-match@1.0.0
├─ brace-expansion@1.1.11
│  ├─ balanced-match@^1.0.0
│  └─ concat-map@0.0.1
├─ callsites@3.1.0
├─ chalk@2.4.2
│  ├─ ansi-styles@^3.2.1
│  ├─ escape-string-regexp@^1.0.5
│  └─ supports-color@^5.3.0
├─ chardet@0.7.0
├─ cli-cursor@3.1.0
│  └─ restore-cursor@^3.1.0
├─ cli-width@2.2.0
├─ color-convert@1.9.3
│  └─ color-name@1.1.3
├─ color-name@1.1.3
├─ concat-map@0.0.1
├─ cross-spawn@6.0.5
│  ├─ nice-try@^1.0.4
│  ├─ path-key@^2.0.1
│  ├─ semver@^5.5.0
│  ├─ semver@5.7.1
│  ├─ shebang-command@^1.2.0
│  └─ which@^1.2.9
├─ debug@4.1.1
│  └─ ms@^2.1.1
├─ deep-is@0.1.3
├─ doctrine@3.0.0
│  └─ esutils@^2.0.2
├─ emoji-regex@7.0.3
├─ escape-string-regexp@1.0.5
├─ eslint-scope@5.0.0
│  ├─ esrecurse@^4.1.0
│  └─ estraverse@^4.1.1
├─ eslint-utils@1.4.3
│  └─ eslint-visitor-keys@^1.1.0
├─ eslint-visitor-keys@1.1.0
├─ eslint@6.8.0
│  ├─ @babel/code-frame@^7.0.0
│  ├─ ajv@^6.10.0
│  ├─ chalk@^2.1.0
│  ├─ cross-spawn@^6.0.5
│  ├─ debug@^4.0.1
│  ├─ doctrine@^3.0.0
│  ├─ eslint-scope@^5.0.0
│  ├─ eslint-utils@^1.4.3
│  ├─ eslint-visitor-keys@^1.1.0
│  ├─ espree@^6.1.2
│  ├─ esquery@^1.0.1
│  ├─ esutils@^2.0.2
│  ├─ file-entry-cache@^5.0.1
│  ├─ functional-red-black-tree@^1.0.1
│  ├─ glob-parent@^5.0.0
│  ├─ globals@^12.1.0
│  ├─ ignore@^4.0.6
│  ├─ import-fresh@^3.0.0
│  ├─ imurmurhash@^0.1.4
│  ├─ inquirer@^7.0.0
│  ├─ is-glob@^4.0.0
│  ├─ js-yaml@^3.13.1
│  ├─ json-stable-stringify-without-jsonify@^1.0.1
│  ├─ levn@^0.3.0
│  ├─ lodash@^4.17.14
│  ├─ minimatch@^3.0.4
│  ├─ mkdirp@^0.5.1
│  ├─ natural-compare@^1.4.0
│  ├─ optionator@^0.8.3
│  ├─ progress@^2.0.0
│  ├─ regexpp@^2.0.1
│  ├─ semver@^6.1.2
│  ├─ strip-ansi@^5.2.0
│  ├─ strip-json-comments@^3.0.1
│  ├─ table@^5.2.3
│  ├─ text-table@^0.2.0
│  └─ v8-compile-cache@^2.0.3
├─ espree@6.1.2
│  ├─ acorn-jsx@^5.1.0
│  ├─ acorn@^7.1.0
│  └─ eslint-visitor-keys@^1.1.0
├─ esprima@4.0.1
├─ esquery@1.0.1
│  └─ estraverse@^4.0.0
├─ esrecurse@4.2.1
│  └─ estraverse@^4.1.0
├─ estraverse@4.3.0
├─ esutils@2.0.3
├─ external-editor@3.1.0
│  ├─ chardet@^0.7.0
│  ├─ iconv-lite@^0.4.24
│  └─ tmp@^0.0.33
├─ fast-deep-equal@2.0.1
├─ fast-json-stable-stringify@2.1.0
├─ fast-levenshtein@2.0.6
├─ figures@3.1.0
│  └─ escape-string-regexp@^1.0.5
├─ file-entry-cache@5.0.1
│  └─ flat-cache@^2.0.1
├─ flat-cache@2.0.1
│  ├─ flatted@^2.0.0
│  ├─ rimraf@2.6.3
│  └─ write@1.0.3
├─ flatted@2.0.1
├─ fs.realpath@1.0.0
├─ functional-red-black-tree@1.0.1
├─ glob-parent@5.1.0
│  └─ is-glob@^4.0.1
├─ glob@7.1.6
│  ├─ fs.realpath@^1.0.0
│  ├─ inflight@^1.0.4
│  ├─ inherits@2
│  ├─ minimatch@^3.0.4
│  ├─ once@^1.3.0
│  └─ path-is-absolute@^1.0.0
├─ globals@12.3.0
│  └─ type-fest@^0.8.1
├─ has-flag@3.0.0
├─ iconv-lite@0.4.24
│  └─ safer-buffer@>= 2.1.2 < 3
├─ ignore@4.0.6
├─ import-fresh@3.2.1
│  ├─ parent-module@^1.0.0
│  └─ resolve-from@^4.0.0
├─ imurmurhash@0.1.4
├─ inflight@1.0.6
│  ├─ once@^1.3.0
│  └─ wrappy@1
├─ inherits@2.0.4
├─ inquirer@7.0.3
│  ├─ ansi-escapes@^4.2.1
│  ├─ ansi-regex@5.0.0
│  ├─ chalk@^2.4.2
│  ├─ cli-cursor@^3.1.0
│  ├─ cli-width@^2.0.0
│  ├─ emoji-regex@8.0.0
│  ├─ external-editor@^3.0.3
│  ├─ figures@^3.0.0
│  ├─ is-fullwidth-code-point@3.0.0
│  ├─ lodash@^4.17.15
│  ├─ mute-stream@0.0.8
│  ├─ run-async@^2.2.0
│  ├─ rxjs@^6.5.3
│  ├─ string-width@^4.1.0
│  ├─ string-width@4.2.0
│  │  ├─ emoji-regex@^8.0.0
│  │  ├─ is-fullwidth-code-point@^3.0.0
│  │  ├─ strip-ansi@^6.0.0
│  │  └─ strip-ansi@6.0.0
│  │     └─ ansi-regex@^5.0.0
│  ├─ strip-ansi@^5.1.0
│  └─ through@^2.3.6
├─ is-extglob@2.1.1
├─ is-fullwidth-code-point@2.0.0
├─ is-glob@4.0.1
│  └─ is-extglob@^2.1.1
├─ is-promise@2.1.0
├─ isexe@2.0.0
├─ js-tokens@4.0.0
├─ js-yaml@3.13.1
│  ├─ argparse@^1.0.7
│  └─ esprima@^4.0.0
├─ json-schema-traverse@0.4.1
├─ json-stable-stringify-without-jsonify@1.0.1
├─ levn@0.3.0
│  ├─ prelude-ls@~1.1.2
│  └─ type-check@~0.3.2
├─ lodash@4.17.15
├─ mimic-fn@2.1.0
├─ minimatch@3.0.4
│  └─ brace-expansion@^1.1.7
├─ minimist@0.0.8
├─ mkdirp@0.5.1
│  └─ minimist@0.0.8
├─ ms@2.1.2
├─ mute-stream@0.0.8
├─ natural-compare@1.4.0
├─ nice-try@1.0.5
├─ once@1.4.0
│  └─ wrappy@1
├─ onetime@5.1.0
│  └─ mimic-fn@^2.1.0
├─ optionator@0.8.3
│  ├─ deep-is@~0.1.3
│  ├─ fast-levenshtein@~2.0.6
│  ├─ levn@~0.3.0
│  ├─ prelude-ls@~1.1.2
│  ├─ type-check@~0.3.2
│  └─ word-wrap@~1.2.3
├─ os-tmpdir@1.0.2
├─ parent-module@1.0.1
│  └─ callsites@^3.0.0
├─ path-is-absolute@1.0.1
├─ path-key@2.0.1
├─ prelude-ls@1.1.2
├─ progress@2.0.3
├─ punycode@2.1.1
├─ regexpp@2.0.1
├─ resolve-from@4.0.0
├─ restore-cursor@3.1.0
│  ├─ onetime@^5.1.0
│  └─ signal-exit@^3.0.2
├─ rimraf@2.6.3
│  └─ glob@^7.1.3
├─ run-async@2.3.0
│  └─ is-promise@^2.1.0
├─ rxjs@6.5.4
│  └─ tslib@^1.9.0
├─ safer-buffer@2.1.2
├─ semver@6.3.0
├─ shebang-command@1.2.0
│  └─ shebang-regex@^1.0.0
├─ shebang-regex@1.0.0
├─ signal-exit@3.0.2
├─ slice-ansi@2.1.0
│  ├─ ansi-styles@^3.2.0
│  ├─ astral-regex@^1.0.0
│  └─ is-fullwidth-code-point@^2.0.0
├─ sprintf-js@1.0.3
├─ string-width@3.1.0
│  ├─ emoji-regex@^7.0.1
│  ├─ is-fullwidth-code-point@^2.0.0
│  └─ strip-ansi@^5.1.0
├─ strip-ansi@5.2.0
│  └─ ansi-regex@^4.1.0
├─ strip-json-comments@3.0.1
├─ supports-color@5.5.0
│  └─ has-flag@^3.0.0
├─ table@5.4.6
│  ├─ ajv@^6.10.2
│  ├─ lodash@^4.17.14
│  ├─ slice-ansi@^2.1.0
│  └─ string-width@^3.0.0
├─ text-table@0.2.0
├─ through@2.3.8
├─ tmp@0.0.33
│  └─ os-tmpdir@~1.0.2
├─ tslib@1.10.0
├─ tsutils@3.17.1
│  └─ tslib@^1.8.1
├─ type-check@0.3.2
│  └─ prelude-ls@~1.1.2
├─ type-fest@0.8.1
├─ typescript@3.7.4
├─ uri-js@4.2.2
│  └─ punycode@^2.1.0
├─ v8-compile-cache@2.1.0
├─ which@1.3.1
│  └─ isexe@^2.0.0
├─ word-wrap@1.2.3
├─ wrappy@1.0.2
└─ write@1.0.3
   └─ mkdirp@^0.5.1
armano2 commented 4 years ago

this is working as it should, if you want to use modules you have to instruct eslint to let you: try adding

    "parserOptions": {
        "sourceType": "module",
    }

Its also good to set ecmaVersion (same as tsconfig) in parserOptions

you can find more info at https://eslint.org/docs/user-guide/configuring#specifying-parser-options and https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration

bradzacher commented 4 years ago

@armano2 - our parser doesn't actually respect this parserOption - typescript has its own logic for determining this.

could you please run your lint run with the --debug flag?

armano2 commented 4 years ago

after reviewing your source code there is issue in name of your eslint config. it has not standard name .eslint.js (eslint is unable to locate it), in case when you want to use js file it should be .eslintrc.js or you should provide config as console argument.

eslint . --ext .js,.jsx,.ts,.tsx -c .eslint.js
#or
eslint . --ext .js,.jsx,.ts,.tsx --config .eslint.js

^ @bradzacher you are correct, parser itself does not use this field but its used in rules and scope analysis (i'm keep forgetting about this)

flisboac commented 4 years ago

after reviewing your source code there is issue in name of your eslint config. it has not standard name .eslint.js (eslint is unable to locate it), in case when you want to use js file it should be .eslintrc.js or you should provide config as console argument.

eslint . --ext .js,.jsx,.ts,.tsx -c .eslint.js
#or
eslint . --ext .js,.jsx,.ts,.tsx --config .eslint.js

^ @bradzacher you are correct, parser itself does not use this field but its used in rules and scope analysis (i'm keep forgetting about this)

Oh god, such a stupid mistake. I'm sorry!

@armano2 @bradzacher thank you very much!