Skip to content

Commit f15bdce

Browse files
authoredJan 25, 2025··
fix(linter): catch Promise in typescript/array-type rule (#8702)
close #8693 Correctly catch `Promise<string[]>` and `Promise<Array<number>>`.
1 parent e8e6917 commit f15bdce

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
lines changed
 

Diff for: ‎crates/oxc_linter/src/rules/typescript/array_type.rs

+69-6
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ fn check(
176176
}
177177

178178
if let TSType::TSTypeReference(ts_type_reference) = &type_annotation {
179-
check_and_report_error_array(default_config, readonly_config, ts_type_reference, ctx);
179+
check_and_report_error_reference(default_config, readonly_config, ts_type_reference, ctx);
180180
}
181181
}
182182

@@ -238,6 +238,65 @@ fn check_and_report_error_generic(
238238
});
239239
}
240240

241+
fn check_and_report_error_reference(
242+
default_config: &ArrayOption,
243+
readonly_config: &ArrayOption,
244+
ts_type_reference: &TSTypeReference,
245+
ctx: &LintContext,
246+
) {
247+
if let TSTypeName::IdentifierReference(ident_ref_type_name) = &ts_type_reference.type_name {
248+
if ident_ref_type_name.name.as_str() == "ReadonlyArray"
249+
|| ident_ref_type_name.name.as_str() == "Array"
250+
{
251+
check_and_report_error_array(default_config, readonly_config, ts_type_reference, ctx);
252+
} else if ident_ref_type_name.name.as_str() == "Promise" {
253+
if let Some(type_params) = &ts_type_reference.type_parameters {
254+
if type_params.params.len() == 1 {
255+
if let Some(type_param) = type_params.params.first() {
256+
if let TSType::TSArrayType(array_type) = &type_param {
257+
check_and_report_error_generic(
258+
default_config,
259+
array_type.span,
260+
&array_type.element_type,
261+
ctx,
262+
false,
263+
);
264+
}
265+
266+
if let TSType::TSTypeOperatorType(ts_operator_type) = &type_param {
267+
if matches!(
268+
&ts_operator_type.operator,
269+
TSTypeOperatorOperator::Readonly
270+
) {
271+
if let TSType::TSArrayType(array_type) =
272+
&ts_operator_type.type_annotation
273+
{
274+
check_and_report_error_generic(
275+
readonly_config,
276+
ts_operator_type.span,
277+
&array_type.element_type,
278+
ctx,
279+
true,
280+
);
281+
}
282+
}
283+
}
284+
285+
if let TSType::TSTypeReference(ts_type_reference) = &type_param {
286+
check_and_report_error_reference(
287+
default_config,
288+
readonly_config,
289+
ts_type_reference,
290+
ctx,
291+
);
292+
}
293+
}
294+
}
295+
}
296+
}
297+
}
298+
}
299+
241300
fn check_and_report_error_array(
242301
default_config: &ArrayOption,
243302
readonly_config: &ArrayOption,
@@ -248,11 +307,6 @@ fn check_and_report_error_array(
248307
return;
249308
};
250309

251-
if ident_ref_type_name.name.as_str() != "ReadonlyArray"
252-
&& ident_ref_type_name.name.as_str() != "Array"
253-
{
254-
return;
255-
}
256310
let is_readonly_array_type = ident_ref_type_name.name == "ReadonlyArray";
257311
let config = if is_readonly_array_type { readonly_config } else { default_config };
258312
if matches!(config, ArrayOption::Generic) {
@@ -1116,6 +1170,10 @@ fn test() {
11161170
"const foo: ReadonlyArray<new (...args: any[]) => void> = [];",
11171171
Some(serde_json::json!([{"default":"array"}])),
11181172
),
1173+
(
1174+
"let a: Promise<string[]> = Promise.resolve([]);",
1175+
Some(serde_json::json!([{"default": "generic"}])),
1176+
),
11191177
];
11201178

11211179
let fix: Vec<(&str, &str, Option<serde_json::Value>)> = vec![
@@ -1643,6 +1701,11 @@ fn test() {
16431701
"const foo: readonly (new (...args: any[]) => void)[] = [];",
16441702
Some(serde_json::json!([{"default":"array"}])),
16451703
),
1704+
(
1705+
"let a: Promise<string[]> = Promise.resolve([]);",
1706+
"let a: Promise<Array<string>> = Promise.resolve([]);",
1707+
Some(serde_json::json!([{"default": "generic"}])),
1708+
),
16461709
];
16471710

16481711
Tester::new(ArrayType::NAME, ArrayType::PLUGIN, pass, fail).expect_fix(fix).test_and_snapshot();

Diff for: ‎crates/oxc_linter/src/snapshots/typescript_array_type.snap

+7
Original file line numberDiff line numberDiff line change
@@ -652,3 +652,10 @@ source: crates/oxc_linter/src/tester.rs
652652
· ───────────────────────────────────────────
653653
╰────
654654
help: Replace `ReadonlyArray<new (...args: any[]) => void>` with `readonly (new (...args: any[]) => void)[]`.
655+
656+
⚠ typescript-eslint(array-type): Array type using 'string[]' is forbidden. Use 'Array<string>' instead.
657+
╭─[array_type.tsx:1:16]
658+
1 │ let a: Promise<string[]> = Promise.resolve([]);
659+
· ────────
660+
╰────
661+
help: Replace `string[]` with `Array<string>`.

0 commit comments

Comments
 (0)