fix(linter): filter by type aware rules when looking up tsgolint rule severity (#28138)

Closes #28136

Severity for tsgolint diagnostics was looked up in the file's resolved
rules by name only. `unicorn/prefer-string-starts-ends-with` has the
same name as `typescript/prefer-string-starts-ends-with`, so whichever
came first in the list won, and the order differs for files that match
an `overrides` entry. Both lookups (CLI and `lint_source`) now only
match type-aware rules.

Added a CLI fixture with the config from the issue; the snapshot shows a
warning for both files, and it fails on main with an error for `b.tsx`.
`cargo test -p oxlint --lib tsgolint`, `cargo test -p oxc_linter --lib`,
clippy and fmt pass.

AI disclosure: I used Claude Code to help trace the cause and write the
patch, and I reviewed and tested it myself.

---------

Co-authored-by: Cameron <cameron.clark@hey.com>
This commit is contained in:
NavpreetSSidhuandCameron authored and GitHub committed 2026-10-23 21:22:35 +00:00
1 parent cf34678cd6
commit 53be530876
7 files changed
+51 -2

No files matched your search

@@ -0,0 +1,7 @@
{
"plugins": ["typescript", "unicorn"],
"categories": { "correctness": "error" },
"options": { "typeAware": true },
"rules": { "typescript/prefer-string-starts-ends-with": "warn" },
"overrides": [{ "files": ["**/*.tsx"], "env": { "browser": true } }]
}
@@ -0,0 +1 @@
export const f = (s: string): boolean => s.substring(0, 3) === 'abc';
@@ -0,0 +1 @@
export const f = (s: string): boolean => s.substring(0, 3) === 'abc';
@@ -0,0 +1 @@
{ "compilerOptions": { "strict": true, "jsx": "react-jsx" }, "include": ["*.ts", "*.tsx"] }
+11
View File
@@ -1940,6 +1940,17 @@ mod test {
Tester::new().with_cwd("fixtures/cli/tsgolint_rule_options".into()).test_and_snapshot(args);
}
#[test]
#[cfg(all(not(target_os = "windows"), not(target_endian = "big")))]
fn test_tsgolint_same_name_rule_severity_with_overrides() {
// `unicorn/prefer-string-starts-ends-with` must not change the severity of the typescript rule
// See: https://github.com/oxc-project/oxc/issues/28136
let args = &["a.ts", "b.tsx"];
Tester::new()
.with_cwd("fixtures/cli/tsgolint_same_name_overrides".into())
.test_and_snapshot(args);
}
#[test]
#[cfg(all(not(target_os = "windows"), not(target_endian = "big")))]
fn test_tsgolint_fix() {
@@ -0,0 +1,25 @@
---
source: apps/oxlint/src/tester.rs
---
##########
arguments: a.ts b.tsx
working directory: fixtures/cli/tsgolint_same_name_overrides
----------
! typescript(prefer-string-starts-ends-with): Use 'String#startsWith' method instead.
,-[a.ts:1:42]
1 | export const f = (s: string): boolean => s.substring(0, 3) === 'abc';
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
! typescript(prefer-string-starts-ends-with): Use 'String#startsWith' method instead.
,-[b.tsx:1:42]
1 | export const f = (s: string): boolean => s.substring(0, 3) === 'abc';
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^
`----
Found 2 warnings and 0 errors.
Finished in <variable>ms on 2 files with 98 rules using 1 threads.
----------
CLI result: LintSucceeded
----------
+5 -2
View File
@@ -217,7 +217,8 @@ impl TsGoLintState {
.rules
.iter()
.find(|(rule, _)| {
rule.name() == tsgolint_diagnostic.rule
rule.is_tsgolint_rule()
&& rule.name() == tsgolint_diagnostic.rule
})
.map(|(_, status)| *status)
})
@@ -475,7 +476,9 @@ impl TsGoLintState {
let severity =
resolved_config.rules.iter().find_map(|(rule, status)| {
if rule.name() == tsgolint_diagnostic.rule {
if rule.is_tsgolint_rule()
&& rule.name() == tsgolint_diagnostic.rule
{
Some(*status)
} else {
None