Skip to content

fix: consistent-type-specifier-style with prefer-inline and TS resolution-mode import attributes#443

Merged
JounQin merged 5 commits intoun-ts:masterfrom
baevm:fix/consistent-type-specifier-style
Feb 26, 2026
Merged

fix: consistent-type-specifier-style with prefer-inline and TS resolution-mode import attributes#443
JounQin merged 5 commits intoun-ts:masterfrom
baevm:fix/consistent-type-specifier-style

Conversation

@baevm
Copy link
Copy Markdown
Contributor

@baevm baevm commented Dec 30, 2025

fixes #233. not sure is it right way to place tests in TS_ONLY array as its TS only feature or in COMMON_TESTS?


Important

Add handling for TypeScript resolution-mode attribute in consistent-type-specifier-style rule to prevent incorrect linting.

  • Behavior:
    • Add hasResolutionModeAttribute() in consistent-type-specifier-style.ts to check for resolution-mode attribute in import declarations.
    • Skip rule enforcement if resolution-mode attribute is present.
  • Tests:
    • Add test cases for resolution-mode attribute in consistent-type-specifier-style.spec.ts under TS_ONLY.
    • Ensure both prefer-inline and prefer-top-level options are tested with resolution-mode.

This description was created by Ellipsis for 126a59c. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • Bug Fixes

    • The consistent-type-specifier-style lint rule now preserves imports that include a resolution-mode attribute, avoiding transformations for both configuration options.
  • Tests

    • Added coverage confirming type-only imports with resolution-mode attributes are valid under both prefer-inline and prefer-top-level.
  • Chores

    • Added a changeset and updated the changelog entry for this fix.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Dec 30, 2025

🦋 Changeset detected

Latest commit: 5df513b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
eslint-plugin-import-x Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 30, 2025

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ade4cea and 5df513b.

📒 Files selected for processing (3)
  • .changeset/salty-brooms-nail.md
  • src/rules/consistent-type-specifier-style.ts
  • test/rules/consistent-type-specifier-style.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/rules/consistent-type-specifier-style.ts
  • test/rules/consistent-type-specifier-style.spec.ts

📝 Walkthrough

Walkthrough

Skip processing ImportDeclarations that include a TypeScript resolution-mode import attribute; the consistent-type-specifier-style rule now early-returns for such imports in both prefer-inline and prefer-top-level modes to preserve them.

Changes

Cohort / File(s) Summary
Rule Implementation
src/rules/consistent-type-specifier-style.ts
Add hasResolutionModeAttribute() detection and early-return guards in both prefer-inline and prefer-top-level branches to avoid transforming imports with a resolution-mode attribute.
Test Coverage
test/rules/consistent-type-specifier-style.spec.ts
Add two TS-only valid tests verifying imports with resolution-mode attributes are accepted under both rule options.
Changelog
.changeset/salty-brooms-nail.md
New changeset entry documenting the exception for TypeScript resolution-mode import attributes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

bug

Suggested reviewers

  • JounQin
  • SukkaW

Poem

🐇 I hop through code with careful paws,

spotting resolution-mode without a pause.
I leave those imports safe and sound,
No linty changes messing them around,
A tiny hop — a tidy cause.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: fixing the consistent-type-specifier-style rule to handle TypeScript resolution-mode import attributes with prefer-inline option.
Linked Issues check ✅ Passed The PR correctly implements the requirement from issue #233 by adding hasResolutionModeAttribute() function and early-return guards in both prefer-inline and prefer-top-level paths to skip enforcement when resolution-mode attribute is present.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the consistent-type-specifier-style rule for resolution-mode attributes; no unrelated modifications are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codesandbox-ci
Copy link
Copy Markdown

codesandbox-ci Bot commented Dec 30, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Copy link
Copy Markdown

@ellipsis-dev ellipsis-dev Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 126a59c in 31 seconds. Click for details.
  • Reviewed 53 lines of code in 2 files
  • Skipped 0 files when reviewing.
  • Skipped posting 3 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. src/rules/consistent-type-specifier-style.ts:47
  • Draft comment:
    The newly added function 'hasResolutionModeAttribute' cleanly checks for a resolution-mode attribute using Array.some. Optionally, you could use optional chaining (e.g. node.attributes?.some(...)) for brevity, but this is acceptable.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. src/rules/consistent-type-specifier-style.ts:95
  • Draft comment:
    The added early return in the prefer-inline branch (using hasResolutionModeAttribute) correctly bypasses fixing resolution-mode type imports, which is essential for TS compliance.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
3. test/rules/consistent-type-specifier-style.spec.ts:225
  • Draft comment:
    The test cases for resolution-mode attributes are placed in the TS_ONLY array, which is appropriate since this is a TypeScript-specific feature. This ensures the behavior is only tested when TS is in use.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None

Workflow ID: wflow_kbOuSYtLnviCEPZW

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/rules/consistent-type-specifier-style.ts (1)

47-56: Consider handling Identifier keys in addition to Literal keys.

The current implementation only checks for Literal keys, but ECMAScript import attributes allow both string literals and identifiers as keys. While TypeScript documentation examples use quoted 'resolution-mode', a defensive check for both forms would be more robust.

🔎 Suggested enhancement to handle both key types
 function hasResolutionModeAttribute(node: TSESTree.ImportDeclaration) {
   return (
     node.attributes &&
     node.attributes.some(
-      attr =>
-        attr.key.type === 'Literal' && attr.key.value === 'resolution-mode',
+      attr => {
+        if (attr.key.type === 'Literal') {
+          return attr.key.value === 'resolution-mode'
+        }
+        if (attr.key.type === 'Identifier') {
+          return attr.key.name === 'resolution-mode'
+        }
+        return false
+      }
     )
   )
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a3aae61 and 126a59c.

📒 Files selected for processing (2)
  • src/rules/consistent-type-specifier-style.ts
  • test/rules/consistent-type-specifier-style.spec.ts
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 271
File: test/rules/no-unused-modules.spec.ts:1528-1532
Timestamp: 2025-03-30T09:06:59.006Z
Learning: The import from 'eslint8.56/use-at-your-own-risk' has incorrect TypeScript types but works correctly at runtime, which is properly handled with a `ts-expect-error` comment.
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 378
File: src/rules/imports-first.ts:10-19
Timestamp: 2025-06-08T12:09:38.535Z
Learning: The current implementation in eslint-plugin-import-x uses the correct ESLint core DeprecatedInfo structure: deprecatedSince field and replacedBy array with objects containing rule properties that match the ExternalSpecifier type with name and url fields.
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 378
File: src/rules/imports-first.ts:10-19
Timestamp: 2025-06-08T12:09:38.535Z
Learning: ESLint core ExternalSpecifier interface has optional name and url string properties. The current eslint-plugin-import-x implementation correctly uses this structure for the rule property within replacedBy arrays in DeprecatedInfo objects.
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 386
File: src/rules/prefer-namespace-import.ts:41-46
Timestamp: 2025-06-18T15:22:38.532Z
Learning: In eslint-plugin-import-x, JounQin prefers to throw on invalid rule options rather than handling them gracefully with try/catch blocks and reporting configuration errors.
📚 Learning: 2025-05-31T03:11:08.864Z
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 362
File: src/utils/import-declaration.ts:1-2
Timestamp: 2025-05-31T03:11:08.864Z
Learning: TypeScript type-only imports (using `import type`) are stripped during compilation and do not affect production dependencies or bundle size. Only runtime imports need to be considered when managing production dependencies in TypeScript projects.

Applied to files:

  • test/rules/consistent-type-specifier-style.spec.ts
  • src/rules/consistent-type-specifier-style.ts
📚 Learning: 2025-03-30T09:06:59.006Z
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 271
File: test/rules/no-unused-modules.spec.ts:1528-1532
Timestamp: 2025-03-30T09:06:59.006Z
Learning: The import from 'eslint8.56/use-at-your-own-risk' has incorrect TypeScript types but works correctly at runtime, which is properly handled with a `ts-expect-error` comment.

Applied to files:

  • test/rules/consistent-type-specifier-style.spec.ts
  • src/rules/consistent-type-specifier-style.ts
📚 Learning: 2025-05-31T03:10:38.972Z
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 362
File: src/utils/create-rule.ts:0-0
Timestamp: 2025-05-31T03:10:38.972Z
Learning: When `rewriteRelativeImportExtensions` is enabled in TypeScript configuration, using `.ts` extensions in import paths is correct and necessary for Node.js ESM compatibility. TypeScript will rewrite these to `.js` during compilation.

Applied to files:

  • test/rules/consistent-type-specifier-style.spec.ts
  • src/rules/consistent-type-specifier-style.ts
📚 Learning: 2025-06-08T12:09:38.535Z
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 378
File: src/rules/imports-first.ts:10-19
Timestamp: 2025-06-08T12:09:38.535Z
Learning: ESLint core ExternalSpecifier interface has optional name and url string properties. The current eslint-plugin-import-x implementation correctly uses this structure for the rule property within replacedBy arrays in DeprecatedInfo objects.

Applied to files:

  • src/rules/consistent-type-specifier-style.ts
📚 Learning: 2025-06-08T12:09:38.535Z
Learnt from: JounQin
Repo: un-ts/eslint-plugin-import-x PR: 378
File: src/rules/imports-first.ts:10-19
Timestamp: 2025-06-08T12:09:38.535Z
Learning: The current implementation in eslint-plugin-import-x uses the correct ESLint core DeprecatedInfo structure: deprecatedSince field and replacedBy array with objects containing rule properties that match the ExternalSpecifier type with name and url fields.

Applied to files:

  • src/rules/consistent-type-specifier-style.ts
📚 Learning: 2025-03-30T14:44:11.779Z
Learnt from: SukkaW
Repo: un-ts/eslint-plugin-import-x PR: 272
File: src/utils/resolve.ts:0-0
Timestamp: 2025-03-30T14:44:11.779Z
Learning: In eslint-plugin-import-x's node resolver, the `modules` parameter of `createNodeResolver` function accepts both string and string array types, making it flexible when passing values like `moduleDirectory`.

Applied to files:

  • src/rules/consistent-type-specifier-style.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
test/rules/consistent-type-specifier-style.spec.ts (1)

225-233: LGTM! Test coverage for resolution-mode exemption is appropriate.

The test cases correctly validate that imports with resolution-mode attributes are exempted under both prefer-inline and prefer-top-level configurations. Placement in the TS_ONLY array is correct since resolution-mode is TypeScript-specific syntax (introduced in TS 5.3).

src/rules/consistent-type-specifier-style.ts (1)

98-100: LGTM! Guard correctly prevents invalid transformation.

The early return when resolution-mode is present prevents the rule from transforming import type {...} with {'resolution-mode': ...} (valid) into import {type ...} with {...} (invalid TypeScript syntax). The placement after the importKind check and before specifier validation is appropriate.

Note: No equivalent guard is needed in the prefer-top-level branch since it already returns early for top-level type imports at line 140.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Dec 30, 2025

Open in StackBlitz

npm i https://pkg.pr.new/eslint-plugin-import-x@443

commit: 5df513b

@JounQin JounQin requested review from SukkaW and Copilot and removed request for SukkaW December 30, 2025 12:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes the consistent-type-specifier-style rule to properly handle TypeScript's resolution-mode import attributes introduced in TypeScript 5.3. The fix prevents the rule from incorrectly attempting to transform imports that include resolution-mode attributes, which are necessary for controlling module resolution behavior.

  • Adds a helper function to detect resolution-mode attributes in import declarations
  • Exempts imports with resolution-mode attributes from the prefer-inline enforcement
  • Adds test coverage for both prefer-inline and prefer-top-level options with resolution-mode

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/rules/consistent-type-specifier-style.ts Adds hasResolutionModeAttribute() helper function and integrates check into prefer-inline branch to skip transformation for imports with resolution-mode
test/rules/consistent-type-specifier-style.spec.ts Adds test cases validating that top-level type imports with resolution-mode attributes are preserved under both configuration options
.changeset/salty-brooms-nail.md Documents the patch-level change for the resolution-mode exception

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/rules/consistent-type-specifier-style.spec.ts
Comment thread src/rules/consistent-type-specifier-style.ts Outdated
Comment thread src/rules/consistent-type-specifier-style.ts Outdated
baevm and others added 4 commits February 26, 2026 18:01
Signed-off-by: JounQin <admin@1stg.me>
Signed-off-by: JounQin <admin@1stg.me>
@JounQin JounQin force-pushed the fix/consistent-type-specifier-style branch from 89e4366 to 5009ec6 Compare February 26, 2026 10:01
@JounQin JounQin changed the title fix: fix consistent-type-specifier-style with prefer-inline and TS resolution-mode import attributes fix: consistent-type-specifier-style with prefer-inline and TS resolution-mode import attributes Feb 26, 2026
@JounQin JounQin enabled auto-merge (squash) February 26, 2026 10:10
@JounQin JounQin merged commit b416a8a into un-ts:master Feb 26, 2026
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

consistent-type-specifier-style: Add exception for resolution-mode import attributes

3 participants