Skip to content

Comments

fix(linter/consistent-indexed-object-style): skip fixing default exported interface#17874

Merged
camc314 merged 4 commits intomainfrom
copilot/fix-linter-invalid-fix
Jan 11, 2026
Merged

fix(linter/consistent-indexed-object-style): skip fixing default exported interface#17874
camc314 merged 4 commits intomainfrom
copilot/fix-linter-invalid-fix

Conversation

Copy link
Contributor

Copilot AI commented Jan 11, 2026

The consistent-indexed-object-style rule was generating invalid TypeScript when converting export default interface with index signatures. TypeScript does not allow export default type, causing the autofix to produce syntax errors.

Changes

  • Skip autofix for export default interfaces: Detect when an interface is exported as default and report the diagnostic without providing an autofix
  • Preserve autofix for named exports: Ensure export interface declarations still get the correct autofix to export type

Example

// Before: Rule would suggest invalid fix
export default interface SchedulerService {
    [key: string]: unknown;
}
// ❌ Invalid: export default type SchedulerService = Record<string, unknown>;

// After: Rule reports error without autofix
// ✅ Users can manually refactor by removing default export or using named export

// Named exports still work correctly:
export interface Foo {
    [key: string]: unknown;
}
// ✅ Valid fix: export type Foo = Record<string, unknown>;
Original prompt

This section details on the original issue you should resolve

<issue_title>linter: Invalid fix for typescript/consistent-indexed-object-style rule</issue_title>
<issue_description>### What version of Oxlint are you using?

unreleased

What command did you run?

No response

What does your .oxlintrc.json config file look like?

N/A

What happened?

See: https://github.com/oxc-project/oxc-ecosystem-ci/actions/runs/20888867135/job/60016741058#step:11:73

I suspect this is due to the changes for consistent-indexed-object-style in #17802

This:

declare module "ember-task-scheduler" {
    export default interface SchedulerService {
        [key: string]: unknown;
    }
}

Becomes:

declare module "ember-task-scheduler" {
    export default type SchedulerService = Record<string, unknown>;
}

And you can't have a default export for a type, apparently.</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Jan 11, 2026
Copilot AI and others added 2 commits January 11, 2026 13:15
Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix linter issue for consistent indexed object style linter: Skip autofix for export default interface in consistent-indexed-object-style Jan 11, 2026
Copilot AI requested a review from camc314 January 11, 2026 13:21
@github-actions github-actions bot added the A-linter Area - Linter label Jan 11, 2026
@camc314 camc314 changed the title linter: Skip autofix for export default interface in consistent-indexed-object-style fix(linter/consistent-indexed-object-style): skip fixing default exported interface Jan 11, 2026
@camc314 camc314 marked this pull request as ready for review January 11, 2026 13:35
Copilot AI review requested due to automatic review settings January 11, 2026 13:35
@github-actions github-actions bot added the C-bug Category - Bug label Jan 11, 2026
@codspeed-hq
Copy link

codspeed-hq bot commented Jan 11, 2026

CodSpeed Performance Report

Merging this PR will not alter performance

Comparing copilot/fix-linter-invalid-fix (78d65a2) with main (51c2815)

Summary

✅ 4 untouched benchmarks
⏩ 41 skipped benchmarks1

Footnotes

  1. 41 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
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-indexed-object-style linter rule to avoid generating invalid TypeScript syntax when attempting to autofix export default interface declarations with index signatures. TypeScript does not allow the syntax export default type, so the rule now skips autofixing for default-exported interfaces while continuing to report the diagnostic.

Changes:

  • Skip autofix for export default interface declarations to prevent invalid export default type syntax
  • Preserve autofix functionality for named export interface declarations
  • Add test cases for both scenarios to ensure correct behavior

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
crates/oxc_linter/src/rules/typescript/consistent_indexed_object_style.rs Added check to detect ExportDefaultDeclaration parent and skip autofix; added test cases for both export default and named export scenarios
crates/oxc_linter/src/snapshots/typescript_consistent_indexed_object_style.snap Updated snapshot to include diagnostic output for the export default interface test case

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

@camc314 camc314 merged commit 76c903f into main Jan 11, 2026
26 of 27 checks passed
@camc314 camc314 deleted the copilot/fix-linter-invalid-fix branch January 11, 2026 13:42
Dunqing pushed a commit that referenced this pull request Jan 12, 2026
# Oxlint
### 🚀 Features

- 9699a1b linter/prefer-global-this: Add suggestion (#17873) (Mikhail
Baev)
- 51c2815 linter/no-invalid-regexp: Add labels and help text to flag
diagnostics (#17865) (camchenry)
- 344d77d linter/no-ex-assign: Improve diagnostic with more detail
(#17864) (camchenry)
- 7d280e0 linter: Add fixer for
`unicorn/no-useless-error-capture-stack-trace` rule (#17839) (Mikhail
Baev)
- af1d0e3 linter/prefer-optional-chain: Add rule (#17831) (camc314)
- e3c4108 vscode: Add more supported languages to extension (#17812)
(Alexander Lichter)
- 4a46678 vscode: Activate extension on more languages (#17717) (Sysix)
- b1298fc vscode: Sync formatter with supported files (#17615)
(Alexander Lichter)
- c7f0848 linte/rno-required-prop-with-default: Implement suggestion
(#17747) (Minsu Lee)
- 0e8127e linter/vue: Implement no-lifecycle-after-await (#17701)
(yefan)
- 3567304 linter/vitest: Implement `consistent-each-for` (#17601) (Said
Atrahouch)
- 883e156 linter: Add fixer for `unicorn/no-useless-collection-argument`
rule (#17594) (Mikhail Baev)
- 4eb335c linter/vitest: Implemented prefer-called-once (#17674) (Said
Atrahouch)
- 2bd2d5a linter/vitest: Implement hoisted-apis-on-top (#17658) (Said
Atrahouch)
- cfb2bcc linter/vue: Implement no-arrow-functions-in-watch (#17672)
(yefan)
- a68208a linter/eslint-plugin-vitest: Implements
`prefer-describe-function-title` (#17677) (Said Atrahouch)
- efa029f linter/vitest: Implement no-unneeded-async-expect-function
(#17494) (Minsu Lee)

### 🐛 Bug Fixes

- 49cf66e lsp: Fix workspace worker selection for nested and
similar-named workspaces (#17853) (Copilot)
- 84f4f3c linter: Add doc url for tsgolint diagnostics (#17879) (Sysix)
- 76c903f linter/consistent-indexed-object-style: Skip fixing default
exported interface (#17874) (Copilot)
- 7e87d16 linter/tabindex-no-positive: Improve diagnostic phrasing
(#17849) (connorshea)
- 28f9fba vscode: Fix nested search for binaries (#17832) (Sysix)
- 8ca2cd2 linter: Move jsx-a11y/no-static-element-interactions rule to
nursery. (#17818) (connorshea)
- dc9fdd6 linter/consistent-indexed-object-style: Re-port test cases and
fix some bugs (#17802) (camc314)
- 7bbd880 linter: Update prefer-destructuring rule metadata (#17642)
(Hamir Mahal)
- 3c45185 linter/consistent-indexed-object-style: False positive with
circular reference (#17789) (heygsc)
- bd186b4 vscode: Search for `oxlint` and `oxfmt` in every workspace
directory (#17760) (Sysix)
- 3e0dff7 linter/no-hooks: Add punctuation to diagnostic message
(#17751) (camc314)
- 6ae21f9 linter/prefer-called-once: Avoid panic on trailing comma
(#17735) (Said Atrahouch)
- 32c3901 oxlint: Do not panic on invalid `no-unused-vars` configuration
(#17719) (Sysix)
- 59a6228 parser: Detect TS1363 error for type-only imports with mixed
default and named/namespace bindings (#17712) (Copilot)

### ⚡ Performance

- f87a1e2 linter: Check for giving reserved plugin name before calling
`load_plugin` on napi side (#17841) (Sysix)

### 📚 Documentation

- a2b3a24 linter/no-caller: Improve docs and diagnostic for rule.
(#17890) (connorshea)
- aa48247 linter/no-unsafe-finally: Improve rule docs. (#17891)
(connorshea)
- 1b0bdee linter: Tweak docs for no-useless-constructor and
hoisted-apis-on-top (#17888) (connorshea)
- 8f24fa9 vscode: Remove mention of a built-in server (#17836) (Sysix)
- e81a306 linter: Update the tsconfig flag mention for the import
plugin. (#17778) (connorshea)
# Oxfmt
### 🚀 Features

- 539b350 formatter/sort_imports: Update `NODE_BUILTINS` modules
(#17771) (nilptr)
- 2e03ebf oxfmt/lsp: Use `SourceFormatter` to support non-JS files and
napi features (#17655) (leaysgur)
- 623f7eb oxfmt/sort_package_json: Use `options.sort_scripts` (#17740)
(leaysgur)
- 86c0168 oxfmt/sort_package_json: Handle `oxfmtrc.sort_scripts` option
(#17738) (leaysgur)
- 256636a oxfmt/lsp: Add `.editorconfig` to `get_watcher_patterns`
(#17694) (leaysgur)
- 3f3db39 oxfmt/lsp: Use `ConfigResolver` to align with CLI (#17654)
(leaysgur)

### 🐛 Bug Fixes

- fdd1e1e formatter: Don't wrap parenthesis for type assertion when it's
an declaration of export default (#17878) (Dunqing)
- f0813ad formatter: Incorrect type annotation check for short argument
(#17877) (Dunqing)
- 9e89389 formatter/tailwindcss: Nested class string doesn't respect
`singleQuote: true` (#17838) (Dunqing)
- e2f534c formatter/sort_imports: Handle alignable comment with JsLabels
(#17791) (leaysgur)
- f0cedd4 formatter/tailwindcss: Class name is broken after sorting when
its contains single quotes with `singleQuote: true` (#17790) (Dunqing)
- 1864142 oxfmt/tailwindcss: Bundle `prettier/plugins/*` (#17782)
(leaysgur)
- 3a9d43b oxfmt: Ignore explicit positional path which is ignored by
directory (#17732) (leaysgur)
- 0563217 formatter: Classes will be stripped out when both
`experimentalTailwindcss` and `experimentalSortImports` are enabled
(#17726) (Dunqing)

### ⚡ Performance

- d1bc514 formatter: Optimize RegExpLiteral formatting to avoid heap
allocations (#17797) (Dunqing)

### 📚 Documentation

- 62b7a01 formatter: Clarify `experimentalTailwindcss` configuration
comments (#17898) (Dunqing)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

linter: Invalid fix for typescript/consistent-indexed-object-style rule

2 participants