eslint-plugin-import icon indicating copy to clipboard operation
eslint-plugin-import copied to clipboard

[import/no-duplicates] (prefer-inline) Autofix merges imports incorrectly

Open KirillGalimov opened this issue 2 years ago • 5 comments

Config:

'import/no-duplicates': ['error', { 'prefer-inline': true }]

Case 1:

input

import type { TypeOne, TypeTwo } from './types';
import type { TypeThree, TypeFour } from './types';

output

import type { TypeOne, TypeTwo, type TypeThree, TypeFour } from './types';

expected

import { type TypeOne, type TypeTwo, type TypeThree, type TypeFour } from './types';

Case 2:

input

import type { TypeOne, TypeTwo } from './types';
import { type TypeThree, type TypeFour } from './types';

output

import type { TypeOne, TypeTwo, type TypeThree, type TypeFour } from './types';

expected

import { type TypeOne, type TypeTwo, type TypeThree, type TypeFour } from './types';

KirillGalimov avatar Jun 05 '23 08:06 KirillGalimov

Another broken prefer-inline autofix case, and a minor inconsistency:

Case 1: Merging type followed by non-type generates uncompilable code:

input

import type { TypeOne } from './other';
import { functionOne } from './other';

output

import type { TypeOne , functionOne } from './other';

expected

import { type TypeOne, functionOne } from './other';

Case 2: Merging non-type followed by type generates correct code but with unusual output spacing:

input

import { functionOne } from './other';
import type { TypeOne } from './other';

output

import { functionOne ,type  TypeOne } from './other'

expected

import { functionOne, type TypeOne } from './other'

kevinbosman avatar Jul 28 '23 13:07 kevinbosman

Another one:

input

import type React from 'react';
import { useId, useState } from 'react';

output

import type React, { useId , useState } from 'react';

expected

import type React from 'react';
import { useId, useState } from 'react';

dylang avatar Sep 27 '23 15:09 dylang

Another case: Merging import type and type only named import results into uncompilable code.

input

import type Highcharts from 'highcharts'
import { type SankeyNodeObject } from 'highcharts'

output

import type Highcharts, { type SankeyNodeObject } from 'highcharts';

expected

import { type default as Highcharts, type SankeyNodeObject } from 'highcharts';

Caution: Although following code looks similar to expected output, it will generate different compiled code from input when verbatimModuleSyntax is enabled in TypeScript compiler options.

import type { default as Highcharts, SankeyNodeObject } from 'highcharts';

frantic1048 avatar Dec 05 '23 02:12 frantic1048

Ran into this today. Original code:

import type { Knex } from 'knex';
import knex from 'knex';

Produces these warnings:

index.ts:3:27
✖    3:27  /project/node_modules/knex/knex.js imported multiple times.    import/no-duplicates
✖    4:18  /project/node_modules/knex/knex.js imported multiple times.    import/no-duplicates

Auto-fixes to:

import knex, type { Knex } from 'knex';

Then when running eslint again:

index.ts:3:13
✖  3:13  Parsing error: { expected.  

1 error

And also produces the following TypeScript error:

index.ts:3:28 - error TS1434: Unexpected keyword or identifier.

3 import knex, type { Knex } from 'knex';

ben-eb avatar Mar 13 '24 12:03 ben-eb

I'd +1 to @frantic1048's expectation rather than @dylang's, as per the rule name no-duplicates, though this should be configurable by a boolean option like mergeTypeDefault with the default value being true.

yuhr avatar Apr 05 '24 07:04 yuhr