Skip to content

fix(linter/no-use-before-define): honor ignoreTypeReferences when value and type name collisions#19747

Merged
camc314 merged 2 commits intooxc-project:mainfrom
Dimava:fix/no-use-before-define-ignore-type-ref-shadowing
Feb 26, 2026
Merged

fix(linter/no-use-before-define): honor ignoreTypeReferences when value and type name collisions#19747
camc314 merged 2 commits intooxc-project:mainfrom
Dimava:fix/no-use-before-define-ignore-type-ref-shadowing

Conversation

@Dimava
Copy link
Contributor

@Dimava Dimava commented Feb 26, 2026

Prevent no-use-before-define from reporting unresolved references in initializers when ignoreTypeReferences is enabled, so type assertions like x as foo are not treated as value self-references.

Made-with: Cursor

fixes #19743

fix(linter): honor ignoreTypeReferences when value and type names collide

Summary

  • Fixes a no-use-before-define false positive in TypeScript when ignoreTypeReferences: true.
  • Prevents unresolved type-only initializer references from being treated as value self-references.
  • Adds a regression test for a global type foo and local variable foo with x as foo.
  • Fixed by GPT-5.3 Codex in Cursor.

Bug Repro

Config:

{
  "rules": {
    "no-use-before-define": ["error", { "ignoreTypeReferences": true, "variables": true }]
  }
}

Input:

declare global {
  type foo = string
}

export function fn(x: unknown) {
  const foo = x as foo
  return foo
}

Expected: no lint error (as foo is type-only).
Actual before fix: 'foo' was used before it was defined.

Root Cause

In the unresolved-reference branch of no-use-before-define, the initializer self-reference fallback path ran without first honoring ignoreTypeReferences.
That allowed unresolved type-only references (like as foo) to be interpreted like value self-references (let foo = foo).

Fix

  • In unresolved-symbol handling, return early when:
    • ignoreTypeReferences is enabled, and
    • the reference is type-only (is_type_reference(...)).
  • Keep existing initializer self-reference behavior for value references unchanged.
  • Add a regression case to the TypeScript ESLint test set.

Files Changed

  • crates/oxc_linter/src/rules/eslint/no_use_before_define.rs

Validation

  • Confirmed regression behavior: test fails without the fix and passes with the fix restored.
  • cargo test -p oxc_linter no_use_before_define::test_typescript_eslint
  • cargo lint -- --deny warnings

Prerequisites Checklist

  • Branch created from origin/main
  • Change is scoped to one rule and includes regression test
  • Root cause identified and fixed (no workaround)
  • No unrelated files included in this change
  • Full lint suite passed (cargo lint -- --deny warnings)
  • Targeted rule tests passed

Test Plan

  • Run cargo test -p oxc_linter no_use_before_define::test_typescript_eslint
  • Verify new test case passes with fix
  • Verify same case fails when guard is temporarily removed (done locally)
  • Run full lint (cargo lint -- --deny warnings)

Notes for Reviewers

  • Behavior change is intentionally narrow: unresolved type-only references are ignored only when ignoreTypeReferences is true.
  • Value-reference ordering checks and initializer self-reference detection remain unchanged.

Prevent no-use-before-define from reporting unresolved references in initializers when ignoreTypeReferences is enabled, so type assertions like `x as foo` are not treated as value self-references.

Made-with: Cursor
@Dimava Dimava requested a review from camc314 as a code owner February 26, 2026 11:17
@github-actions github-actions bot added A-linter Area - Linter C-bug Category - Bug labels Feb 26, 2026
@camc314 camc314 changed the title fix(linter): honor ignoreTypeReferences when value and type names collide fix(linter/no-use-before-define): honor ignoreTypeReferences when value and type name collisions Feb 26, 2026
Copy link
Contributor

@camc314 camc314 left a comment

Choose a reason for hiding this comment

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

Thank yoU!

@camc314 camc314 self-assigned this Feb 26, 2026
@camc314 camc314 merged commit 7243a58 into oxc-project:main Feb 26, 2026
20 checks passed
@codspeed-hq
Copy link

codspeed-hq bot commented Feb 26, 2026

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 51 skipped benchmarks1


Comparing Dimava:fix/no-use-before-define-ignore-type-ref-shadowing (017ba9f) with main (e2c5c63)

Open in CodSpeed

Footnotes

  1. 51 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.

camc314 pushed a commit that referenced this pull request Mar 2, 2026
# Oxlint
### 🚀 Features

- 2e0e1d0 linter/no-unused-vars: Add experimental fix mode controls
(off|suggestion|fix) (#19774) (camc314)
- f34f6fa linter: Introduce typeCheck config option (#19764) (camc314)
- 694be7d linter: Introduce typeAware as config options (#19614)
(camc314)
- 655c38f semantic: Add "did you mean?" suggestions to undefined name
errors (#19102) (copilot-swe-agent)
- e97a57e linter/id-length: Use serde to deserialize rule options
(#19636) (camc314)
- c4a3677 parser: Report error for initializer in ambient context
(#19187) (camc314)
- 346045a linter/id-length: Add `checkGeneric` option (#19634) (camc314)

### 🐛 Bug Fixes

- 1b7a937 linter: Correct double-comparisons fix with swapped operands
(#19846) (camc314)
- c308857 linter/consistent_type_imports: Add missing help and notes to
diagnostics (#19827) (Daniel Osmond)
- 7682e5a linter/plugins: Decode escapes in identifier tokens (#19838)
(overlookmotel)
- f368fcd linter/consistent_type_assertions: Add missing with_help and
with_note to diagnostics (#19826) (Daniel Osmond)
- 04e6223 npm: Add `preferUnplugged` for Yarn PnP compatibility (#19829)
(Boshen)
- 86d5037 linter: Add help text to no-extend-native,
no-useless-backreference (#19733) (Anthony Amaro)
- 50e8eff linter: Add .with_help() to operator-assignment,
no-nonoctal-decimal-escape (#19732) (Anthony Amaro)
- 1417bdc linter/no-wrapper-object-types: Add help messages to missing
diagnostics (#19771) (Daniel Osmond)
- 0838477 linter/ban_ts_comment: Add help and notes to missing
diagnostics (#19781) (Daniel Osmond)
- e8c77cf linter/adjacent_overload_signatures: Add missing diagnostics
(#19780) (Daniel Osmond)
- 28834ac linter/ban_types: Add missing help and note to diagnostics
(#19782) (Daniel Osmond)
- fd938d3 linter/prefer-enum-initializers: Add help messages to missing
diagnostics (#19772) (Daniel Osmond)
- eb928ee linter/no-dynamic-delete: Add help messages to missing
diagnostics (#19768) (Daniel Osmond)
- a985666 linter/no-empty-interface: Add help messages to missing
diagnostics (#19769) (Daniel Osmond)
- 2dc0ceb linter/no-extra-non-null-assertion: Add help messages to
missing diagnostics (#19770) (Daniel Osmond)
- 95d5d66 linter/no-dupe-keys: Handle `__proto__` proto setters in
(#19762) (camc314)
- 24ff0db linter/exhaustive-deps: False positive for member expressions
in IIFEs (#19751) (Dennis Chen)
- 7243a58 linter/no-use-before-define: Honor `ignoreTypeReferences` when
value and type name collisions (#19747) (Dimava)
- eefd818 linter/explicit-module-boundary-types: Add help messages to
missing diagnostics (#19736) (Daniel Osmond)
- 0440e9a linter: Add help text to no_control_regex, no_fallthrough,
no_param_reassign (#19655) (Anthony Amaro)
- e84cb2f react/display-name: Handle merged type+value context symbols
(#19608) (camc314)
- ce7e253 linter/prefer-object-from-entries: Require exact path match in
unicorn helper (#19687) (camc314)
- f5694ce estree/tokens: Reverse field order of `regex` object in tokens
(#19679) (overlookmotel)
- b2b7a55 estree/tokens: Generate tokens for files with BOM (#19535)
(overlookmotel)
- 0722721 linter/jsx-curly-brace-presence: False positive with prop &
mixed quotes (#19674) (camc314)
- 3496acd linter: Enhance diagnostic help messages for eslint rules
(#19653) (Anthony Amaro)
- e384e94 linter: Enhance help diagnostic messages for more eslint rules
(#19658) (Anthony Amaro)
- a4d5b34 linter: Avoid non-promise catch false positives (#19574)
(camc314)
- 5706f38 linter: `unicorn/no-array-callback-reference` skip `Effect.*`
array-like methods name. (#19633) (Said Atrahouch)

### ⚡ Performance

- 05ccf9f linter/plugins: Transfer tokens via raw transfer (#19893)
(overlookmotel)
- 4b0611a estree/tokens: Introduce `ESTreeTokenConfig` trait (#19842)
(overlookmotel)
- ec88f6a estree/tokens: Serialize tokens while visiting AST (#19726)
(overlookmotel)
- d4dcf26 linter/plugins: Remove `typescript` from bundle (#19531)
(overlookmotel)
- 6a6513c linter/plugins: Use Oxc tokens in plugins (#19498) (camc314)

### 📚 Documentation

- d86f59e linter: Improve docs for no-useless-concat, mark as pending
fixer. (#19859) (connorshea)
- caa091d linter/plugins: Correct doc comments for `initTokens` (#19530)
(overlookmotel)
- 2fa936f README.md: Map npm package links to npmx.dev (#19666) (Boshen)
- dc0ff73 linter/no-useless-constructor: Warn for parameter properties
as well (#19638) (Ole Asteo)
# Oxfmt
### 🚀 Features

- 5141bc2 formatter: Support trailing ignore comments (#19304) (Andreas
Lubbe)
- 4888a99 oxfmt/lsp: Support other schemes beside `file://` and
`untitled://` (#19872) (Sysix)
- 14a0181 oxfmt: Support `graphql()` variant for gql-in-js (#19703)
(leaysgur)
- ca68ea6 oxfmt: Support gql-in-js substitution (#19670) (leaysgur)
- 035933c formatter,oxfmt: Support js-in-vue (partially) (#19514)
(leaysgur)
- 9e11dc6 parser,estree,coverage: Collect tokens in parser and convert
to ESTree format (#19497) (camc314)

### 🐛 Bug Fixes

- 8e3842d oxfmt: Avoid embedded TSFN crash by returning errors as data
(take2) (#19806) (Yuji Sugiura)
- 04e6223 npm: Add `preferUnplugged` for Yarn PnP compatibility (#19829)
(Boshen)
- e540585 oxfmt: Support tailwind sort for CSS/LESS/SCSS (#19803)
(leaysgur)
- 93bb861 formatter: Trim trailing whitespace before breaking line
(#19740) (leaysgur)
- b85f97b formatter: Drop blank line between terminal call and first
chain member (#19659) (Dunqing)

### ⚡ Performance

- b3b2d30 parser: Introduce `ParserConfig` (#19637) (overlookmotel)

### 📚 Documentation

- 2fa936f README.md: Map npm package links to npmx.dev (#19666) (Boshen)

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: ignoreTypeReferences not applied when variable name matches global type name

2 participants