diff --git a/crates/oxc_linter/src/generated/rule_runner_impls.rs b/crates/oxc_linter/src/generated/rule_runner_impls.rs index 4035d8d931827..db4a4955210ab 100644 --- a/crates/oxc_linter/src/generated/rule_runner_impls.rs +++ b/crates/oxc_linter/src/generated/rule_runner_impls.rs @@ -2532,6 +2532,7 @@ impl RuleRunner for crate::rules::typescript::array_type::ArrayType { AstType::TSConditionalType, AstType::TSIndexedAccessType, AstType::TSMappedType, + AstType::TSSatisfiesExpression, AstType::TSTypeAliasDeclaration, AstType::TSTypeAnnotation, AstType::TSTypeParameterInstantiation, diff --git a/crates/oxc_linter/src/rules/typescript/array_type.rs b/crates/oxc_linter/src/rules/typescript/array_type.rs index 1e607fdeecf30..92adc8326ad35 100644 --- a/crates/oxc_linter/src/rules/typescript/array_type.rs +++ b/crates/oxc_linter/src/rules/typescript/array_type.rs @@ -179,6 +179,15 @@ impl Rule for ArrayType { ctx, ); } + // for example: [] as const satisfies readonly string[]; + AstKind::TSSatisfiesExpression(ts_satisfies_expression) => { + check( + &ts_satisfies_expression.type_annotation, + self.default_config(), + self.readonly_config(), + ctx, + ); + } AstKind::TSTypeReference(ts_type_reference) if outermost_paren_parent(node, ctx).is_some_and(|x| match x.kind() { AstKind::TSTypeAliasDeclaration(TSTypeAliasDeclaration { @@ -965,6 +974,15 @@ const instance = new MyClass(42);", "let z: readonly factories.User[] = [];", Some(serde_json::json!([{"readonly":"array-simple"}])), ), + // TSSatisfiesExpression + ( + "const x = [] as const satisfies string[];", + Some(serde_json::json!([{"default":"array"}])), + ), + ( + "const x = [] as const satisfies ReadonlyArray;", + Some(serde_json::json!([{"default":"array-simple","readonly":"generic"}])), + ), ]; let fail = vec![ @@ -1456,6 +1474,20 @@ export const test8 = testFn, number[]>([]);", "type MakeArrays = { [K in keyof T]: T[K][] };", Some(serde_json::json!([{"default":"generic"}])), ), + // TSSatisfiesExpression - https://github.com/oxc-project/oxc/issues/16897 + ( + "const x = [] as const satisfies readonly string[];", + Some(serde_json::json!([{"default":"array-simple","readonly":"generic"}])), + ), + ( + "const x = [] as const satisfies Array;", + Some(serde_json::json!([{"default":"array"}])), + ), + // nested: only outer Array should be reported, inner string[] is correct + ( + "const x = [] satisfies Array;", + Some(serde_json::json!([{"default":"array"}])), + ), ]; let fix: Vec<(&str, &str, Option)> = vec![ @@ -2103,6 +2135,23 @@ export const test9 = testFn>([]);", export const test9 = testFn([]);", Some(serde_json::json!([{"default":"array-simple"}])), ), + // TSSatisfiesExpression - https://github.com/oxc-project/oxc/issues/16897 + ( + "const x = [] as const satisfies readonly string[];", + "const x = [] as const satisfies ReadonlyArray;", + Some(serde_json::json!([{"default":"array-simple","readonly":"generic"}])), + ), + ( + "const x = [] as const satisfies Array;", + "const x = [] as const satisfies string[];", + Some(serde_json::json!([{"default":"array"}])), + ), + // nested: only outer Array should be fixed + ( + "const x = [] satisfies Array;", + "const x = [] satisfies string[][];", + Some(serde_json::json!([{"default":"array"}])), + ), ]; Tester::new(ArrayType::NAME, ArrayType::PLUGIN, pass, fail) diff --git a/crates/oxc_linter/src/snapshots/typescript_array_type.snap b/crates/oxc_linter/src/snapshots/typescript_array_type.snap index e5681a421fdc8..8c1232747e169 100644 --- a/crates/oxc_linter/src/snapshots/typescript_array_type.snap +++ b/crates/oxc_linter/src/snapshots/typescript_array_type.snap @@ -1,5 +1,6 @@ --- source: crates/oxc_linter/src/tester.rs +assertion_line: 394 --- ⚠ typescript-eslint(array-type): Array type using 'factories.User[]' is forbidden. Use 'Array' instead. ╭─[array_type.ts:1:8] @@ -901,3 +902,24 @@ source: crates/oxc_linter/src/tester.rs · ────── ╰──── help: Replace `T[K][]` with `Array`. + + ⚠ typescript-eslint(array-type): Array type using 'readonly string[]' is forbidden. Use 'ReadonlyArray' instead. + ╭─[array_type.ts:1:33] + 1 │ const x = [] as const satisfies readonly string[]; + · ───────────────── + ╰──── + help: Replace `readonly string[]` with `ReadonlyArray`. + + ⚠ typescript-eslint(array-type): Array type using 'Array' is forbidden. Use 'string[]' instead. + ╭─[array_type.ts:1:33] + 1 │ const x = [] as const satisfies Array; + · ───────────── + ╰──── + help: Replace `Array` with `string[]`. + + ⚠ typescript-eslint(array-type): Array type using 'Array' is forbidden. Use 'string[][]' instead. + ╭─[array_type.ts:1:24] + 1 │ const x = [] satisfies Array; + · ─────────────── + ╰──── + help: Replace `Array` with `string[][]`.