diff --git a/README.md b/README.md index 7695ac368d..3e60280a80 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ rules: You may use the following shortcut or assemble your own config using the granular settings described below. -Make sure you have installed the [`@typescript-eslint/parser`] which is used in the following configuration. Unfortunately NPM does not allow to list optional peer dependencies. +Make sure you have installed [`@typescript-eslint/parser`] which is used in the following configuration. Unfortunately NPM does not allow to list optional peer dependencies. ```yaml extends: @@ -344,14 +344,16 @@ directly using webpack, for example: # .eslintrc.yml settings: import/parsers: - typescript-eslint-parser: [ .ts, .tsx ] + @typescript-eslint/parser: [ .ts, .tsx ] ``` -In this case, [`typescript-eslint-parser`](https://github.com/eslint/typescript-eslint-parser) must be installed and require-able from -the running `eslint` module's location (i.e., install it as a peer of ESLint). +In this case, [`@typescript-eslint/parser`](https://www.npmjs.com/package/@typescript-eslint/parser) +must be installed and require-able from the running `eslint` module's location +(i.e., install it as a peer of ESLint). -This is currently only tested with `typescript-eslint-parser` but should theoretically -work with any moderately ESTree-compliant parser. +This is currently only tested with `@typescript-eslint/parser` (and its predecessor, +`typescript-eslint-parser`) but should theoretically work with any moderately +ESTree-compliant parser. It's difficult to say how well various plugin features will be supported, too, depending on how far down the rabbit hole goes. Submit an issue if you find strange diff --git a/package.json b/package.json index 51fd070ed4..2cafc4fe5d 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ }, "homepage": "https://github.com/benmosher/eslint-plugin-import", "devDependencies": { + "@typescript-eslint/parser": "^1.5.0", "babel-eslint": "^8.2.6", "babel-plugin-istanbul": "^4.1.6", "babel-preset-es2015-argon": "latest", @@ -67,9 +68,10 @@ "nyc": "^11.9.0", "redux": "^3.7.2", "rimraf": "^2.6.3", + "semver": "^6.0.0", "sinon": "^2.4.1", "typescript": "^3.2.2", - "typescript-eslint-parser": "^21.0.2" + "typescript-eslint-parser": "^22.0.0" }, "peerDependencies": { "eslint": "2.x - 5.x" diff --git a/src/ExportMap.js b/src/ExportMap.js index 61900db03b..20ed009d76 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -465,6 +465,7 @@ ExportMap.parse = function (path, content, context) { case 'TypeAlias': // flowtype with babel-eslint parser case 'InterfaceDeclaration': case 'TSEnumDeclaration': + case 'TSTypeAliasDeclaration': case 'TSInterfaceDeclaration': case 'TSAbstractClassDeclaration': case 'TSModuleDeclaration': diff --git a/tests/dep-time-travel.sh b/tests/dep-time-travel.sh index eae24998df..fcd3cda1dc 100755 --- a/tests/dep-time-travel.sh +++ b/tests/dep-time-travel.sh @@ -4,6 +4,12 @@ npm install --no-save eslint@$ESLINT_VERSION --ignore-scripts || true +# completely remove the new typescript parser for ESLint < v5 +if [[ "$ESLINT_VERSION" -lt "5" ]]; then + echo "Removing @typescript-eslint/parser..." + npm uninstall @typescript-eslint/parser +fi + # use these alternate typescript dependencies for ESLint < v4 if [[ "$ESLINT_VERSION" -lt "4" ]]; then echo "Downgrading babel-eslint..." diff --git a/tests/src/core/getExports.js b/tests/src/core/getExports.js index 80e9d843e3..7207ff34a9 100644 --- a/tests/src/core/getExports.js +++ b/tests/src/core/getExports.js @@ -1,4 +1,6 @@ import { expect } from 'chai' +import semver from 'semver' +import { linter } from 'eslint' import ExportMap from '../../../src/ExportMap' import * as fs from 'fs' @@ -317,6 +319,10 @@ describe('ExportMap', function () { ['array form', { 'typescript-eslint-parser': ['.ts', '.tsx'] }], ] + if (semver.satisfies(linter.version, '>5.0.0')) { + configs.push(['array form', { '@typescript-eslint/parser': ['.ts', '.tsx'] }]) + } + configs.forEach(([description, parserConfig]) => { describe(description, function () { diff --git a/tests/src/rules/named.js b/tests/src/rules/named.js index 569f3158a5..a3f55b35e4 100644 --- a/tests/src/rules/named.js +++ b/tests/src/rules/named.js @@ -1,5 +1,6 @@ import { test, SYNTAX_CASES } from '../utils' -import { RuleTester } from 'eslint' +import { RuleTester, linter } from 'eslint' +import semver from 'semver' import { CASE_SENSITIVE_FS } from 'eslint-module-utils/resolve' @@ -254,99 +255,107 @@ ruleTester.run('named (export *)', rule, { }) -context("Typescript", function () { +context('Typescript', function () { // Typescript - ruleTester.run("named", rule, { - valid: [ - test({ - code: 'import { MyType } from "./typescript"', - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: 'import { Foo } from "./typescript"', - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: 'import { Bar } from "./typescript"', - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: 'import { getFoo } from "./typescript"', - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: 'import { MyEnum } from "./typescript"', - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: ` - import { MyModule } from "./typescript" - MyModule.ModuleFunction() - `, - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - test({ - code: ` - import { MyNamespace } from "./typescript" - MyNamespace.NSModule.NSModuleFunction() - `, - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - }), - ], - - invalid: [ - test({ - code: 'import { MissingType } from "./typescript"', - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - errors: [{ - message: "MissingType not found in './typescript'", - type: 'Identifier', - }], - }), - test({ - code: 'import { NotExported } from "./typescript"', - parser: 'typescript-eslint-parser', - settings: { - 'import/parsers': { 'typescript-eslint-parser': ['.ts'] }, - 'import/resolver': { 'eslint-import-resolver-typescript': true }, - }, - errors: [{ - message: "NotExported not found in './typescript'", - type: 'Identifier', - }], - }), - ] + const parsers = ['typescript-eslint-parser'] + + if (semver.satisfies(linter.version, '>5.0.0')) { + parsers.push('@typescript-eslint/parser') + } + + parsers.forEach((parser) => { + ruleTester.run('named', rule, { + valid: [ + test({ + code: 'import { MyType } from "./typescript"', + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + test({ + code: 'import { Foo } from "./typescript"', + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + test({ + code: 'import { Bar } from "./typescript"', + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + test({ + code: 'import { getFoo } from "./typescript"', + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + test({ + code: 'import { MyEnum } from "./typescript"', + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + test({ + code: ` + import { MyModule } from "./typescript" + MyModule.ModuleFunction() + `, + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + test({ + code: ` + import { MyNamespace } from "./typescript" + MyNamespace.NSModule.NSModuleFunction() + `, + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }), + ], + + invalid: [ + test({ + code: 'import { MissingType } from "./typescript"', + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + errors: [{ + message: "MissingType not found in './typescript'", + type: 'Identifier', + }], + }), + test({ + code: 'import { NotExported } from "./typescript"', + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + errors: [{ + message: "NotExported not found in './typescript'", + type: 'Identifier', + }], + }), + ], + }) }) }) diff --git a/tests/src/rules/order.js b/tests/src/rules/order.js index 23487dac91..dde5ae6cbe 100644 --- a/tests/src/rules/order.js +++ b/tests/src/rules/order.js @@ -1,4 +1,4 @@ -import { test } from '../utils' +import { test, testVersion } from '../utils' import { RuleTester } from 'eslint' @@ -1276,5 +1276,21 @@ ruleTester.run('order', rule, { message: '`fs` import should occur before import of `async`', }], }), - ], + // fix incorrect order with @typescript-eslint/parser + testVersion('>5.0.0', { + code: ` + var async = require('async'); + var fs = require('fs'); + `, + output: ` + var fs = require('fs'); + var async = require('async'); + `, + parser: '@typescript-eslint/parser', + errors: [{ + ruleId: 'order', + message: '`fs` import should occur before import of `async`', + }], + }), + ].filter((t) => !!t), }) diff --git a/tests/src/utils.js b/tests/src/utils.js index 52e2d23cd5..70c5971a6a 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -1,4 +1,6 @@ import path from 'path' +import { linter } from 'eslint' +import semver from 'semver' // warms up the module cache. this import takes a while (>500ms) import 'babel-eslint' @@ -9,6 +11,10 @@ export function testFilePath(relativePath) { export const FILENAME = testFilePath('foo.js') +export function testVersion(specifier, t) { + return semver.satisfies(linter.version) && test(t) +} + export function test(t) { return Object.assign({ filename: FILENAME,