diff --git a/.README/rules/type-import-style.md b/.README/rules/type-import-style.md index 1e61dfda..003e3f3d 100644 --- a/.README/rules/type-import-style.md +++ b/.README/rules/type-import-style.md @@ -12,6 +12,8 @@ import {type T, type U, type V} from '...'; import type {T, U, V} from '...'; ``` +#### Options + The rule has a string option: * `"identifier"` (default): Enforces that type imports are all in the @@ -19,4 +21,8 @@ The rule has a string option: * `"declaration"`: Enforces that type imports are all in the 'declaration' style. +This rule has an object option: + +* `ignoreTypeDefault` - if `true`, when in "identifier" mode, default type imports will be ignored. Default is `false`. + diff --git a/src/rules/typeImportStyle.js b/src/rules/typeImportStyle.js index c92596bf..259d5b8c 100644 --- a/src/rules/typeImportStyle.js +++ b/src/rules/typeImportStyle.js @@ -2,6 +2,15 @@ const schema = [ { enum: ['declaration', 'identifier'], type: 'string' + }, + { + additionalProperties: false, + properties: { + ignoreTypeDefault: { + type: 'boolean' + } + }, + type: 'object' } ]; @@ -23,28 +32,41 @@ const create = (context) => { }; } else { // Default to 'identifier' + const ignoreTypeDefault = context.options[1] && + context.options[1].ignoreTypeDefault; + return { ImportDeclaration (node) { - if (node.importKind === 'type') { - context.report({ - fix (fixer) { - const imports = node.specifiers.map((specifier) => { - if (specifier.type === 'ImportDefaultSpecifier') { - return 'type default as ' + specifier.local.name; - } else if (specifier.imported.name === specifier.local.name) { - return 'type ' + specifier.local.name; - } else { - return 'type ' + specifier.imported.name + ' as ' + specifier.local.name; - } - }); - const source = node.source.value; + if (node.importKind !== 'type') { + return; + } - return fixer.replaceText(node, 'import {' + imports.join(', ') + '} from \'' + source + '\';'); - }, - message: 'Unexpected "import type"', - node - }); + if ( + ignoreTypeDefault && + node.specifiers[0] && + node.specifiers[0].type === 'ImportDefaultSpecifier' + ) { + return; } + + context.report({ + fix (fixer) { + const imports = node.specifiers.map((specifier) => { + if (specifier.type === 'ImportDefaultSpecifier') { + return 'type default as ' + specifier.local.name; + } else if (specifier.imported.name === specifier.local.name) { + return 'type ' + specifier.local.name; + } else { + return 'type ' + specifier.imported.name + ' as ' + specifier.local.name; + } + }); + const source = node.source.value; + + return fixer.replaceText(node, 'import {' + imports.join(', ') + '} from \'' + source + '\';'); + }, + message: 'Unexpected "import type"', + node + }); } }; } diff --git a/tests/rules/assertions/typeImportStyle.js b/tests/rules/assertions/typeImportStyle.js index 33cccaa3..1beb939a 100644 --- a/tests/rules/assertions/typeImportStyle.js +++ b/tests/rules/assertions/typeImportStyle.js @@ -43,6 +43,14 @@ export default { { code: 'import type {A, B} from \'a\';', options: ['declaration'] + }, + { + code: 'import typeof * as A from \'a\';', + options: ['identifier'] + }, + { + code: 'import type A from \'a\';', + options: ['identifier', {ignoreTypeDefault: true}] } ] };