From 43f4e57d6f9aea62affa7260bb35c423d57bfab6 Mon Sep 17 00:00:00 2001 From: auvred Date: Sun, 30 Jul 2023 10:41:49 +0000 Subject: [PATCH] fix(eslint-plugin): [no-restricted-imports] allow inline type qualifiers when `allowTypeImports` enabled --- .../src/rules/no-restricted-imports.ts | 17 +++- .../tests/rules/no-restricted-imports.test.ts | 80 +++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-restricted-imports.ts b/packages/eslint-plugin/src/rules/no-restricted-imports.ts index 28f001fcaaf0..71da6fe6c14d 100644 --- a/packages/eslint-plugin/src/rules/no-restricted-imports.ts +++ b/packages/eslint-plugin/src/rules/no-restricted-imports.ts @@ -1,4 +1,5 @@ import type { TSESTree } from '@typescript-eslint/utils'; +import { AST_NODE_TYPES } from '@typescript-eslint/utils'; import type { JSONSchema4AnyOfSchema, JSONSchema4ArraySchema, @@ -269,8 +270,15 @@ export default createRule({ } return { - ImportDeclaration(node): void { - if (node.importKind === 'type') { + ImportDeclaration(node: TSESTree.ImportDeclaration): void { + if ( + node.importKind === 'type' || + node.specifiers.every( + specifier => + specifier.type === AST_NODE_TYPES.ImportSpecifier && + specifier.importKind === 'type', + ) + ) { const importSource = node.source.value.trim(); if ( !isAllowedTypeImportPath(importSource) && @@ -287,7 +295,10 @@ export default createRule({ source: NonNullable; }, ): void { - if (node.exportKind === 'type') { + if ( + node.exportKind === 'type' || + node.specifiers.every(specifier => specifier.exportKind === 'type') + ) { const importSource = node.source.value.trim(); if ( !isAllowedTypeImportPath(importSource) && diff --git a/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts b/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts index 1f3e4748b118..da3e78884914 100644 --- a/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts +++ b/packages/eslint-plugin/tests/rules/no-restricted-imports.test.ts @@ -254,6 +254,36 @@ import type { foo } from 'import2/private/bar'; }, ], }, + { + code: "import { type Bar } from 'import-foo';", + options: [ + { + paths: [ + { + name: 'import-foo', + importNames: ['Bar'], + message: 'Please use Bar from /import-bar/baz/ instead.', + allowTypeImports: true, + }, + ], + }, + ], + }, + { + code: "export { type Bar } from 'import-foo';", + options: [ + { + paths: [ + { + name: 'import-foo', + importNames: ['Bar'], + message: 'Please use Bar from /import-bar/baz/ instead.', + allowTypeImports: true, + }, + ], + }, + ], + }, ], invalid: [ { @@ -586,5 +616,55 @@ import type { foo } from 'import2/private/bar'; }, ], }, + { + code: "import { Bar, type Baz } from 'import-foo';", + options: [ + { + paths: [ + { + name: 'import-foo', + importNames: ['Bar', 'Baz'], + message: 'Please use Bar and Baz from /import-bar/baz/ instead.', + allowTypeImports: true, + }, + ], + }, + ], + errors: [ + { + messageId: 'importNameWithCustomMessage', + type: AST_NODE_TYPES.ImportDeclaration, + }, + { + messageId: 'importNameWithCustomMessage', + type: AST_NODE_TYPES.ImportDeclaration, + }, + ], + }, + { + code: "export { Bar, type Baz } from 'import-foo';", + options: [ + { + paths: [ + { + name: 'import-foo', + importNames: ['Bar', 'Baz'], + message: 'Please use Bar and Baz from /import-bar/baz/ instead.', + allowTypeImports: true, + }, + ], + }, + ], + errors: [ + { + messageId: 'importNameWithCustomMessage', + type: AST_NODE_TYPES.ExportNamedDeclaration, + }, + { + messageId: 'importNameWithCustomMessage', + type: AST_NODE_TYPES.ExportNamedDeclaration, + }, + ], + }, ], });