diff --git a/crates/oxc_linter/src/rules/import/no_duplicates.rs b/crates/oxc_linter/src/rules/import/no_duplicates.rs index f2cc2fc2eac00..cbf15b3846345 100644 --- a/crates/oxc_linter/src/rules/import/no_duplicates.rs +++ b/crates/oxc_linter/src/rules/import/no_duplicates.rs @@ -1,10 +1,36 @@ +use std::borrow::Cow; + use itertools::Itertools; use oxc_diagnostics::{LabeledSpan, OxcDiagnostic}; use oxc_macros::declare_oxc_lint; +use oxc_span::Span; use oxc_syntax::module_record::{ImportImportName, RequestedModule}; use crate::{context::LintContext, rule::Rule}; +fn no_duplicates_diagnostic( + module_name: &str, + first_import: Span, + other_imports: I, +) -> OxcDiagnostic +where + I: IntoIterator, +{ + const MAX_MODULE_LEN: usize = 16; + + let message = if module_name.len() > MAX_MODULE_LEN { + Cow::Borrowed("Modules should not be imported multiple times in the same file") + } else { + Cow::Owned(format!("Module '{module_name}' is imported more than once in this file")) + }; + let labels = std::iter::once(first_import.primary_label("It is first imported here")) + .chain(other_imports.into_iter().map(LabeledSpan::underline)); + + OxcDiagnostic::warn(message) + .with_labels(labels) + .with_help("Merge these imports into a single import statement") +} + /// #[derive(Debug, Default, Clone)] pub struct NoDuplicates { @@ -64,23 +90,6 @@ impl Rule for NoDuplicates { }) .chunk_by(|r| r.0.clone()); - let check_duplicates = |requested_modules: Option<&Vec<&RequestedModule>>| { - if let Some(requested_modules) = requested_modules { - if requested_modules.len() > 1 { - let labels = requested_modules - .iter() - .map(|requested_module| LabeledSpan::underline(requested_module.span())) - .collect::>(); - ctx.diagnostic( - OxcDiagnostic::warn( - "Forbid repeated import of the same module in multiple places", - ) - .with_labels(labels), - ); - } - } - }; - for (_path, group) in &groups { let has_type_import = module_record.import_entries.iter().any(|entry| entry.is_type); // When prefer_inline is false, 0 is value, 1 is type named, 2 is type namespace and 3 is type default @@ -110,10 +119,20 @@ impl Rule for NoDuplicates { 0 }); - check_duplicates(import_entries_maps.get(&0)); - check_duplicates(import_entries_maps.get(&1)); - check_duplicates(import_entries_maps.get(&2)); - check_duplicates(import_entries_maps.get(&3)); + for i in 0..4 { + check_duplicates(ctx, import_entries_maps.get(&i)); + } + } + } +} + +fn check_duplicates(ctx: &LintContext, requested_modules: Option<&Vec<&RequestedModule>>) { + if let Some(requested_modules) = requested_modules { + if requested_modules.len() > 1 { + let mut labels = requested_modules.iter().map(|m| m.span()); + let first = labels.next().unwrap(); // we know there is at least one + let module_name = ctx.source_range(first).trim_matches('\'').trim_matches('"'); + ctx.diagnostic(no_duplicates_diagnostic(module_name, first, labels)); } } } diff --git a/crates/oxc_linter/src/snapshots/no_duplicates.snap b/crates/oxc_linter/src/snapshots/no_duplicates.snap index b324be44c1eca..934a9b780ef8a 100644 --- a/crates/oxc_linter/src/snapshots/no_duplicates.snap +++ b/crates/oxc_linter/src/snapshots/no_duplicates.snap @@ -1,68 +1,88 @@ --- source: crates/oxc_linter/src/tester.rs --- - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:19] 1 │ import { x } from './foo'; import { y } from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo'; import {y} from './foo'; import { z } from './foo' - · ─────── ─────── ─────── + · ───┬─── ─────── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places - ╭─[index.ts:1:15] + ⚠ eslint-plugin-import(no-duplicates): Module './bar?optionX' is imported more than once in this file + ╭─[index.ts:1:49] 1 │ import x from './bar.js?optionX'; import y from './bar?optionX'; - · ────────────────── ─────────────── + · ────────────────── ───────┬─────── + · │ ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places - ╭─[index.ts:1:15] + ⚠ eslint-plugin-import(no-duplicates): Module './bar?optionY' is imported more than once in this file + ╭─[index.ts:1:46] 1 │ import x from './bar?optionX'; import y from './bar?optionY'; - · ─────────────── ─────────────── + · ─────────────── ───────┬─────── + · │ ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places - ╭─[index.ts:1:15] + ⚠ eslint-plugin-import(no-duplicates): Module './bar.js?optionX' is imported more than once in this file + ╭─[index.ts:1:46] 1 │ import x from './bar?optionX'; import y from './bar.js?optionX'; - · ─────────────── ────────────────── + · ─────────────── ─────────┬──────── + · │ ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module 'non-existent' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import foo from 'non-existent'; import bar from 'non-existent'; - · ────────────── ────────────── + · ───────┬────── ────────────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:24] 1 │ import type { x } from './foo'; import type { y } from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:8] 1 │ import './foo'; import './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:28] 1 │ import { x, /* x */ } from './foo'; import {//y - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ y//y2 3 │ } from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo'; import {} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement × Identifier `a` has already been declared ╭─[index.ts:1:9] @@ -144,221 +164,279 @@ source: crates/oxc_linter/src/tester.rs · ╰── `a` has already been declared here ╰──── - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo'; import {} from './foo'; import {/*c*/} from './foo'; import {y} from './foo' - · ─────── ─────── ─────── ─────── + · ───┬─── ─────── ─────── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import { } from './foo'; import {x} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:8] 1 │ import './foo'; import {x} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:7] 1 │ import'./foo'; import {x} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:8] 1 │ import './foo'; import { /*x*/} from './foo'; import {//y - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here 2 │ } from './foo'; import {z} from './foo' · ─────── ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:8] 1 │ import './foo'; import def, {x} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:8] 1 │ import './foo'; import def from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import def from './foo'; import {x} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo'; import def from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:16] 1 │ import{x} from './foo'; import def from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo'; import def, {y} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import * as ns1 from './foo'; import * as ns2 from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:21] 1 │ import * as ns from './foo'; import {x} from './foo'; import {y} from './foo' - · ─────── ─────── ─────── + · ───┬─── ─────── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo'; import * as ns from './foo'; import {y} from './foo'; import './foo' - · ─────── ─────── ─────── ─────── + · ───┬─── ─────── ─────── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:2:29] 1 │ // some-tool-disable-next-line 2 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 3 │ import {//y 4 │ y} from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ // some-tool-disable-next-line 3 │ import {y} from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' // some-tool-disable-line - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import {y} from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import {y} from './foo' // some-tool-disable-line · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ /* comment */ import {y} from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import {y} from './foo' /* comment · ─────── 3 │ multiline */ ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import {y} from './foo' · ─────── 3 │ // some-tool-disable-next-line ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ // comment 3 │ 4 │ import {y} from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import/* comment */{y} from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import/* comment */'./foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import{y}/* comment */from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:17] 1 │ import {x} from './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import{y}from/* comment */'./foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:3:13] 2 │ // some-tool-disable-next-line 3 │ './foo' - · ─────── + · ───┬─── + · ╰── It is first imported here 4 │ import {y} from './foo' · ─────── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:21] 1 │ import { Foo } from './foo'; - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import { Bar } from './foo'; · ─────── 3 │ export const value = {} ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:21] 1 │ import { Foo } from './foo'; - · ─────── + · ───┬─── + · ╰── It is first imported here 2 │ import Bar from './foo'; · ─────── 3 │ export const value = {} ╰──── + help: Merge these imports into a single import statement × Unexpected token ╭─[index.ts:12:16] @@ -368,22 +446,25 @@ source: crates/oxc_linter/src/tester.rs 13 │ } ╰──── - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module 'foo' is imported more than once in this file ╭─[index.ts:1:19] 1 │ import {A1,} from 'foo'; - · ───── + · ──┬── + · ╰── It is first imported here 2 │ import {B1,} from 'foo'; · ───── 3 │ import {C1,} from 'foo'; · ───── 4 │ ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module 'bar' is imported more than once in this file ╭─[index.ts:7:20] 6 │ A2, 7 │ } from 'bar'; - · ───── + · ──┬── + · ╰── It is first imported here 8 │ import { 9 │ B2, 10 │ } from 'bar'; @@ -393,12 +474,15 @@ source: crates/oxc_linter/src/tester.rs 13 │ } from 'bar'; · ───── ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:20] 1 │ import type x from './foo'; import type y from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement × Identifier `x` has already been declared ╭─[index.ts:1:13] @@ -408,50 +492,66 @@ source: crates/oxc_linter/src/tester.rs · ╰── `x` has already been declared here ╰──── - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import type {x} from './foo'; import type {y} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import {type x} from './foo'; import type {y} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module 'foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import {type x} from 'foo'; import type {y} from 'foo' - · ───── ───── + · ──┬── ───── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module 'foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import {type x} from 'foo'; import type {y} from 'foo' - · ───── ───── + · ──┬── ───── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import {type x} from './foo'; import {type y} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import {type x} from './foo'; import {type y} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:38] 1 │ import {AValue, type x, BValue} from './foo'; import {type y} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement - ⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places + ⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file ╭─[index.ts:1:22] 1 │ import {AValue} from './foo'; import type {AType} from './foo' - · ─────── ─────── + · ───┬─── ─────── + · ╰── It is first imported here ╰──── + help: Merge these imports into a single import statement