Skip to content

Commit 2f6fe05

Browse files
committed
fix(linter/consistent-type-definition): skip comments when looking for token
1 parent 1611b4f commit 2f6fe05

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

crates/oxc_linter/src/context/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ impl<'a> LintContext<'a> {
135135
span.source_text(self.parent.semantic().source_text())
136136
}
137137

138+
/// Finds the next occurrence of the given token in the source code,
139+
/// starting from the specified position, skipping over comments.
140+
#[expect(clippy::cast_possible_truncation)]
141+
pub fn find_next_token_from(&self, start: u32, token: &str) -> Option<u32> {
142+
let source =
143+
self.source_range(Span::new(start, self.parent.semantic().source_text().len() as u32));
144+
145+
source
146+
.match_indices(token)
147+
.find(|(a, _)| !self.is_inside_comment(start + *a as u32))
148+
.map(|(a, _)| a as u32)
149+
}
150+
138151
/// Path to the file currently being linted.
139152
#[inline]
140153
pub fn file_path(&self) -> &Path {

crates/oxc_linter/src/rules/typescript/consistent_type_definitions.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ impl Rule for ConsistentTypeDefinitions {
117117
{
118118
let start = if decl.declare {
119119
let base_start = decl.span.start + 7;
120-
ctx.source_range(Span::new(base_start, decl.span.end))
121-
.find("type")
122-
.map_or(base_start + 1, |v| u32::try_from(v).unwrap_or(0) + base_start)
120+
121+
ctx.find_next_token_from(base_start, "type")
122+
.map_or(base_start + 1, |v| v + base_start)
123123
} else {
124124
decl.span.start
125125
};
@@ -201,9 +201,9 @@ impl Rule for ConsistentTypeDefinitions {
201201
{
202202
let start = if decl.declare {
203203
let base_start = decl.span.start + 7;
204-
ctx.source_range(Span::new(base_start, decl.span.end))
205-
.find("interface")
206-
.map_or(base_start + 1, |v| u32::try_from(v).unwrap_or(0) + base_start)
204+
205+
ctx.find_next_token_from(base_start, "interface")
206+
.map_or(base_start + 1, |v| v + base_start)
207207
} else {
208208
decl.span.start
209209
};
@@ -383,6 +383,8 @@ fn test() {
383383
("declare…interface S {}", Some(serde_json::json!(["type"]))),
384384
("export declare…type S={}", Some(serde_json::json!(["interface"]))),
385385
("export declare…interface S {}", Some(serde_json::json!(["type"]))),
386+
("declare /* interface */ interface T { x: number; };", Some(serde_json::json!(["type"]))),
387+
("declare /* type */ type T = { x: number; };", Some(serde_json::json!(["interface"]))),
386388
];
387389

388390
let fix = vec![

crates/oxc_linter/src/snapshots/typescript_consistent_type_definitions.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,17 @@ source: crates/oxc_linter/src/tester.rs
174174
· ─────────
175175
╰────
176176
help: Use an `type` instead of a `interface`
177+
178+
typescript-eslint(consistent-type-definitions): Use an `type` instead of a `interface`
179+
╭─[consistent_type_definitions.tsx:1:25]
180+
1 │ declare /* interface */ interface T { x: number; };
181+
· ─────────
182+
╰────
183+
help: Use an `type` instead of a `interface`
184+
185+
typescript-eslint(consistent-type-definitions): Use an `interface` instead of a `type`
186+
╭─[consistent_type_definitions.tsx:1:20]
187+
1 │ declare /* type */ type T = { x: number; };
188+
· ────
189+
╰────
190+
help: Use an `interface` instead of a `type`

0 commit comments

Comments
 (0)