diff --git a/src/rules/no-duplicates.js b/src/rules/no-duplicates.js index ada5f668e1..735347f02a 100644 --- a/src/rules/no-duplicates.js +++ b/src/rules/no-duplicates.js @@ -92,13 +92,10 @@ function getInlineTypeFix(nodes, sourceCode) { return fixer => { const fixes = []; - // if (!semver.satisfies(typescriptPkg.version, '>= 4.5')) { - // throw new Error('Your version of TypeScript does not support inline type imports.'); - // } - // push to first import let [firstImport, ...rest] = nodes; - const valueImport = nodes.find((n) => n.specifiers.every((spec) => spec.importKind === 'value')) || nodes.find((n) => n.specifiers.some((spec) => spec.type === 'ImportDefaultSpecifier')); + // const valueImport = nodes.find((n) => n.specifiers.every((spec) => spec.importKind === 'value')) || nodes.find((n) => n.specifiers.some((spec) => spec.type === 'ImportDefaultSpecifier')); + const valueImport = nodes.find((n) => n.specifiers.some((spec) => spec.type === 'ImportDefaultSpecifier')); if (valueImport) { firstImport = valueImport; rest = nodes.filter((n) => n !== firstImport); @@ -106,9 +103,13 @@ function getInlineTypeFix(nodes, sourceCode) { const nodeTokens = sourceCode.getTokens(firstImport); // we are moving the rest of the Type or Inline Type imports here. - const nodeClosingBrace = nodeTokens.find(token => isPunctuator(token, '}')); - // const preferInline = context.options[0] && context.options[0]['prefer-inline']; + const nodeClosingBraceIndex = nodeTokens.findIndex(token => isPunctuator(token, '}')); + const nodeClosingBrace = nodeTokens[nodeClosingBraceIndex]; + const previousToken = nodeTokens[nodeClosingBraceIndex - 1]; if (nodeClosingBrace) { + if (rest.length && isComma(previousToken)) { + fixes.push(fixer.remove(previousToken)); + } rest.forEach((node) => { // these will be all Type imports, no Value specifiers // then add inline type specifiers to importKind === 'type' import diff --git a/tests/src/rules/no-duplicates.js b/tests/src/rules/no-duplicates.js index 5d9cff4187..0185af00d8 100644 --- a/tests/src/rules/no-duplicates.js +++ b/tests/src/rules/no-duplicates.js @@ -614,6 +614,23 @@ context('TypeScript', function () { }, ], }), + test({ + code: "import {type x} from './foo'; import {y} from './foo'", + ...parserConfig, + output: `import {type x, y} from './foo'; `, + errors: [ + { + line: 1, + column: 22, + message: "'./foo' imported multiple times.", + }, + { + line: 1, + column: 47, + message: "'./foo' imported multiple times.", + }, + ], + }), ].concat(!tsVersionSatisfies('>= 4.5') || !typescriptEslintParserSatisfies('>= 5.7.0') ? [] : [ // without prefer-inline, will dedupe with type import kind test({ @@ -1018,6 +1035,24 @@ context('TypeScript', function () { }, ], }), + test({ + code: "import { type C, } from './foo';import {AValue, BValue, } from './foo';", + ...parserConfig, + options: [{ 'prefer-inline': true }], + output: "import { type C , AValue, BValue} from './foo';", + errors: [ + { + line: 1, + column: 25, + message: "'./foo' imported multiple times.", + }, + { + line: 1, + column: 64, + message: "'./foo' imported multiple times.", + }, + ], + }), ]); ruleTester.run('no-duplicates', rule, {