diff --git a/CHANGELOG.md b/CHANGELOG.md index bbfaa0fb9..fe7f6771b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange - [`no-duplicates`]: remove duplicate identifiers in duplicate imports ([#2577], thanks [@joe-matsec]) - [`consistent-type-specifier-style`]: fix accidental removal of comma in certain cases ([#2754], thanks [@bradzacher]) - [Perf] `ExportMap`: Improve `ExportMap.for` performance on larger codebases ([#2756], thanks [@leipert]) +- [`no-extraneous-dependencies`]/TypeScript: do not error when importing inline type from dev dependencies ([#1820], thanks [@andyogo]) ### Changed - [Docs] [`no-duplicates`]: fix example schema ([#2684], thanks [@simmo]) @@ -1070,6 +1071,7 @@ for info on changes for earlier releases. [#2756]: https://github.com/import-js/eslint-plugin-import/pull/2756 [#2754]: https://github.com/import-js/eslint-plugin-import/pull/2754 [#2748]: https://github.com/import-js/eslint-plugin-import/pull/2748 +[#2735]: https://github.com/import-js/eslint-plugin-import/pull/2735 [#2699]: https://github.com/import-js/eslint-plugin-import/pull/2699 [#2664]: https://github.com/import-js/eslint-plugin-import/pull/2664 [#2613]: https://github.com/import-js/eslint-plugin-import/pull/2613 @@ -1625,6 +1627,7 @@ for info on changes for earlier releases. [@alexgorbatchev]: https://github.com/alexgorbatchev [@andreubotella]: https://github.com/andreubotella [@AndrewLeedham]: https://github.com/AndrewLeedham +[@andyogo]: https://github.com/andyogo [@aravindet]: https://github.com/aravindet [@arvigeus]: https://github.com/arvigeus [@asapach]: https://github.com/asapach diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index 68cd4b154..660875d1d 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -12,6 +12,7 @@ Modules have to be installed for this rule to work. This rule supports the following options: `devDependencies`: If set to `false`, then the rule will show an error when `devDependencies` are imported. Defaults to `true`. +Type imports are ignored by default. `optionalDependencies`: If set to `false`, then the rule will show an error when `optionalDependencies` are imported. Defaults to `true`. diff --git a/src/rules/no-extraneous-dependencies.js b/src/rules/no-extraneous-dependencies.js index d6437c2fd..a149ca659 100644 --- a/src/rules/no-extraneous-dependencies.js +++ b/src/rules/no-extraneous-dependencies.js @@ -178,7 +178,12 @@ function reportIfMissing(context, deps, depsOptions, node, name) { // Do not report when importing types unless option is enabled if ( !depsOptions.verifyTypeImports && - (node.importKind === 'type' || node.importKind === 'typeof') + (node.importKind === 'type' || node.importKind === 'typeof' || + ( + Array.isArray(node.specifiers) && + node.specifiers.length && + node.specifiers.every((specifier) => specifier.importKind === 'type' || specifier.importKind === 'typeof')) + ) ) { return; } diff --git a/tests/src/rules/no-extraneous-dependencies.js b/tests/src/rules/no-extraneous-dependencies.js index 8815f63cd..84aa8bb35 100644 --- a/tests/src/rules/no-extraneous-dependencies.js +++ b/tests/src/rules/no-extraneous-dependencies.js @@ -438,7 +438,7 @@ describe('TypeScript', () => { test(Object.assign({ code: 'import type T from "a";', - options: [{ + options: [{ packageDir: packageDirWithTypescriptDevDependencies, devDependencies: false, includeTypes: true, @@ -464,6 +464,16 @@ typescriptRuleTester.run('no-extraneous-dependencies typescript type imports', r filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'), parser: parsers.BABEL_OLD, }), + test({ + code: 'import { type MyType } from "not-a-dependency";', + filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'), + parser: parsers.BABEL_OLD, + }), + test({ + code: 'import { type MyType, type OtherType } from "not-a-dependency";', + filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'), + parser: parsers.BABEL_OLD, + }), ], invalid: [ test({ @@ -476,7 +486,7 @@ typescriptRuleTester.run('no-extraneous-dependencies typescript type imports', r }], }), test({ - code: `import type { Foo } from 'not-a-dependency'`, + code: `import type { Foo } from 'not-a-dependency';`, options: [{ includeTypes: true }], filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'), parser: parsers.BABEL_OLD, @@ -484,5 +494,21 @@ typescriptRuleTester.run('no-extraneous-dependencies typescript type imports', r message: `'not-a-dependency' should be listed in the project's dependencies. Run 'npm i -S not-a-dependency' to add it`, }], }), + test({ + code: 'import Foo, { type MyType } from "not-a-dependency";', + filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'), + parser: parsers.BABEL_OLD, + errors: [{ + message: `'not-a-dependency' should be listed in the project's dependencies. Run 'npm i -S not-a-dependency' to add it`, + }], + }), + test({ + code: 'import { type MyType, Foo } from "not-a-dependency";', + filename: testFilePath('./no-unused-modules/typescript/file-ts-a.ts'), + parser: parsers.BABEL_OLD, + errors: [{ + message: `'not-a-dependency' should be listed in the project's dependencies. Run 'npm i -S not-a-dependency' to add it`, + }], + }), ], });