fix(isolated-declarations): align readonly class array initializer diagnostics with tsc (#19218)

This commit is contained in:
camc314 committed 2026-02-10 14:51:49 +00:00
1 parent 3ea8f08364
commit 3e0e5ba49f
5 files changed
+335 -13

No files matched your search

+17 -12
View File
@@ -5,8 +5,9 @@ use oxc_span::{ContentEq, GetSpan, SPAN};
use crate::{
IsolatedDeclarations,
diagnostics::{
accessor_must_have_explicit_return_type, computed_property_name, extends_clause_expression,
method_must_have_explicit_return_type, property_must_have_explicit_type,
accessor_must_have_explicit_return_type, array_inferred, computed_property_name,
extends_clause_expression, method_must_have_explicit_return_type,
property_must_have_explicit_type,
},
};
@@ -108,17 +109,11 @@ impl<'a> IsolatedDeclarations<'a> {
if let Some(initializer) = self.get_literal_const_initializer(expr) {
value = Some(initializer);
None
} else if Self::is_need_to_infer_type_from_expression(expr) {
self.transform_expression_to_ts_type(expr)
} else if Self::is_non_const_array_literal(expr) {
self.error(array_inferred(expr.span()));
Some(self.ast.ts_type_unknown_keyword(expr.span()))
} else {
if let Expression::TemplateLiteral(lit) = expr {
value = self
.transform_template_to_string(lit)
.map(Expression::StringLiteral);
} else {
value = Some(expr.clone_in(self.ast.allocator));
}
None
self.transform_expression_to_ts_type(expr)
}
} else {
self.infer_type_from_expression(expr)
@@ -175,6 +170,16 @@ impl<'a> IsolatedDeclarations<'a> {
}
}
fn is_non_const_array_literal(expr: &Expression<'a>) -> bool {
match expr {
Expression::ArrayExpression(_) => true,
Expression::ParenthesizedExpression(expr) => {
Self::is_non_const_array_literal(&expr.expression)
}
_ => false,
}
}
fn transform_class_method_definition(
&self,
definition: &MethodDefinition<'a>,
@@ -24,3 +24,15 @@ export class ReadonlyLiteralInitializers {
writableObject = { a: 1 };
writableTrue = true;
}
const values = [1, 2] as const;
export class ReadonlyArrayInitializers {
readonly emptyArray = [];
readonly arrayAsConst = [] as const;
readonly arrayWithTypeAnnotation: number[] = [];
readonly nonEmptyArray = [1, 2];
readonly arrayWithSpread = [...values];
readonly arrayIdentifierReference = [values];
readonly arrayIdentifierReferenceAndAnnotation: [readonly [1,2]] = [values];
}
@@ -0,0 +1,41 @@
const tuple = [1, 2] as const;
const n = 3;
declare function fn(): number;
export class ReadonlyClassPropertyVariations {
readonly emptyArray = [];
readonly emptyArrayAsConst = [] as const;
readonly emptyArrayWithTypeAnnotation: number[] = [];
readonly emptyArrayAsTypeAssertion = [] as number[];
readonly emptyArrayAsConstTypeAssertion = <const>[];
readonly nestedEmptyArrayAsConst = (([] as const));
readonly arrayWithNumberLiterals = [1, 2, 3];
readonly arrayWithMixedLiterals = [1, "x", true, null, undefined];
readonly arrayWithElision = [, 1, , 2];
readonly arrayWithOnlyElision = [,,];
readonly arrayAsConst = [1, "x", true] as const;
readonly nestedArray = [[1], [] as const, [1, 2] as const];
readonly arrayWithObjectLiterals = [{ a: 1 }, { b: "x" as const }];
readonly arrayWithUnaryNumberLiterals = [-1, +2];
readonly arrayWithNoExprTemplateLiteral = [`x`];
readonly arrayWithUndefinedIdentifier = [undefined];
readonly arrayWithConstAssertedElements = [({ a: 1 } as const), ([1, 2] as const)];
readonly arrayWithSpreadConstTuple = [...tuple];
readonly arrayWithSpreadLiteral = [...[1, 2]];
readonly arrayWithIdentifierElement = [tuple];
readonly arrayWithCallElement = [fn()];
readonly arrayWithTemplateExprElement = [`x${n}`];
readonly arrayWithInvalidUnaryElement = [+"x"];
readonly arraySatisfies = [] satisfies number[];
readonly arrayNonNull = []!;
readonly invalidDirectUnary = +"x";
readonly invalidTemplateLiteral = `x${n}`;
readonly annotatedSpread: readonly number[] = [...tuple];
readonly annotatedIdentifier: readonly [1, 2] = tuple;
readonly annotatedCall: unknown[] = [fn()];
readonly annotatedTemplateExpr: string[] = [`x${n}`];
}
@@ -1,6 +1,5 @@
---
source: crates/oxc_isolated_declarations/tests/mod.rs
assertion_line: 54
input_file: crates/oxc_isolated_declarations/tests/fixtures/readonly-class-property-initializer.ts
---
```
@@ -45,3 +44,50 @@ export declare class ReadonlyLiteralInitializers {
};
writableTrue: boolean;
}
export declare class ReadonlyArrayInitializers {
readonly emptyArray: unknown;
readonly arrayAsConst: readonly [];
readonly arrayWithTypeAnnotation: number[];
readonly nonEmptyArray: unknown;
readonly arrayWithSpread: unknown;
readonly arrayIdentifierReference: unknown;
readonly arrayIdentifierReferenceAndAnnotation: [readonly [1, 2]];
}
==================== Errors ====================
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[31:25]
30 | export class ReadonlyArrayInitializers {
31 | readonly emptyArray = [];
: ^^
32 | readonly arrayAsConst = [] as const;
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[34:28]
33 | readonly arrayWithTypeAnnotation: number[] = [];
34 | readonly nonEmptyArray = [1, 2];
: ^^^^^^
35 | readonly arrayWithSpread = [...values];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[35:30]
34 | readonly nonEmptyArray = [1, 2];
35 | readonly arrayWithSpread = [...values];
: ^^^^^^^^^^^
36 | readonly arrayIdentifierReference = [values];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[36:39]
35 | readonly arrayWithSpread = [...values];
36 | readonly arrayIdentifierReference = [values];
: ^^^^^^^^
37 | readonly arrayIdentifierReferenceAndAnnotation: [readonly [1,2]] = [values];
`----
```
@@ -0,0 +1,218 @@
---
source: crates/oxc_isolated_declarations/tests/mod.rs
input_file: crates/oxc_isolated_declarations/tests/fixtures/readonly-class-property-variations.ts
---
```
==================== .D.TS ====================
export declare class ReadonlyClassPropertyVariations {
readonly emptyArray: unknown;
readonly emptyArrayAsConst: readonly [];
readonly emptyArrayWithTypeAnnotation: number[];
readonly emptyArrayAsTypeAssertion: number[];
readonly emptyArrayAsConstTypeAssertion: readonly [];
readonly nestedEmptyArrayAsConst: readonly [];
readonly arrayWithNumberLiterals: unknown;
readonly arrayWithMixedLiterals: unknown;
readonly arrayWithElision: unknown;
readonly arrayWithOnlyElision: unknown;
readonly arrayAsConst: readonly [1, "x", true];
readonly nestedArray: unknown;
readonly arrayWithObjectLiterals: unknown;
readonly arrayWithUnaryNumberLiterals: unknown;
readonly arrayWithNoExprTemplateLiteral: unknown;
readonly arrayWithUndefinedIdentifier: unknown;
readonly arrayWithConstAssertedElements: unknown;
readonly arrayWithSpreadConstTuple: unknown;
readonly arrayWithSpreadLiteral: unknown;
readonly arrayWithIdentifierElement: unknown;
readonly arrayWithCallElement: unknown;
readonly arrayWithTemplateExprElement: unknown;
readonly arrayWithInvalidUnaryElement: unknown;
readonly arraySatisfies;
readonly arrayNonNull;
readonly invalidDirectUnary;
readonly invalidTemplateLiteral;
readonly annotatedSpread: readonly number[];
readonly annotatedIdentifier: readonly [1, 2];
readonly annotatedCall: unknown[];
readonly annotatedTemplateExpr: string[];
}
==================== Errors ====================
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[7:25]
6 | export class ReadonlyClassPropertyVariations {
7 | readonly emptyArray = [];
: ^^
8 | readonly emptyArrayAsConst = [] as const;
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[14:38]
13 |
14 | readonly arrayWithNumberLiterals = [1, 2, 3];
: ^^^^^^^^^
15 | readonly arrayWithMixedLiterals = [1, "x", true, null, undefined];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[15:37]
14 | readonly arrayWithNumberLiterals = [1, 2, 3];
15 | readonly arrayWithMixedLiterals = [1, "x", true, null, undefined];
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16 | readonly arrayWithElision = [, 1, , 2];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[16:31]
15 | readonly arrayWithMixedLiterals = [1, "x", true, null, undefined];
16 | readonly arrayWithElision = [, 1, , 2];
: ^^^^^^^^^^
17 | readonly arrayWithOnlyElision = [,,];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[17:35]
16 | readonly arrayWithElision = [, 1, , 2];
17 | readonly arrayWithOnlyElision = [,,];
: ^^^^
18 | readonly arrayAsConst = [1, "x", true] as const;
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[19:26]
18 | readonly arrayAsConst = [1, "x", true] as const;
19 | readonly nestedArray = [[1], [] as const, [1, 2] as const];
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20 | readonly arrayWithObjectLiterals = [{ a: 1 }, { b: "x" as const }];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[20:38]
19 | readonly nestedArray = [[1], [] as const, [1, 2] as const];
20 | readonly arrayWithObjectLiterals = [{ a: 1 }, { b: "x" as const }];
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21 | readonly arrayWithUnaryNumberLiterals = [-1, +2];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[21:43]
20 | readonly arrayWithObjectLiterals = [{ a: 1 }, { b: "x" as const }];
21 | readonly arrayWithUnaryNumberLiterals = [-1, +2];
: ^^^^^^^^
22 | readonly arrayWithNoExprTemplateLiteral = [`x`];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[22:45]
21 | readonly arrayWithUnaryNumberLiterals = [-1, +2];
22 | readonly arrayWithNoExprTemplateLiteral = [`x`];
: ^^^^^
23 | readonly arrayWithUndefinedIdentifier = [undefined];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[23:43]
22 | readonly arrayWithNoExprTemplateLiteral = [`x`];
23 | readonly arrayWithUndefinedIdentifier = [undefined];
: ^^^^^^^^^^^
24 | readonly arrayWithConstAssertedElements = [({ a: 1 } as const), ([1, 2] as const)];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[24:45]
23 | readonly arrayWithUndefinedIdentifier = [undefined];
24 | readonly arrayWithConstAssertedElements = [({ a: 1 } as const), ([1, 2] as const)];
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25 |
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[26:40]
25 |
26 | readonly arrayWithSpreadConstTuple = [...tuple];
: ^^^^^^^^^^
27 | readonly arrayWithSpreadLiteral = [...[1, 2]];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[27:37]
26 | readonly arrayWithSpreadConstTuple = [...tuple];
27 | readonly arrayWithSpreadLiteral = [...[1, 2]];
: ^^^^^^^^^^^
28 | readonly arrayWithIdentifierElement = [tuple];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[28:41]
27 | readonly arrayWithSpreadLiteral = [...[1, 2]];
28 | readonly arrayWithIdentifierElement = [tuple];
: ^^^^^^^
29 | readonly arrayWithCallElement = [fn()];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[29:35]
28 | readonly arrayWithIdentifierElement = [tuple];
29 | readonly arrayWithCallElement = [fn()];
: ^^^^^^
30 | readonly arrayWithTemplateExprElement = [`x${n}`];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[30:43]
29 | readonly arrayWithCallElement = [fn()];
30 | readonly arrayWithTemplateExprElement = [`x${n}`];
: ^^^^^^^^^
31 | readonly arrayWithInvalidUnaryElement = [+"x"];
`----
x TS9017: Only const arrays can be inferred with --isolatedDeclarations.
,-[31:43]
30 | readonly arrayWithTemplateExprElement = [`x${n}`];
31 | readonly arrayWithInvalidUnaryElement = [+"x"];
: ^^^^^^
32 | readonly arraySatisfies = [] satisfies number[];
`----
x TS9012: Property must have an explicit type annotation with
| --isolatedDeclarations.
,-[32:12]
31 | readonly arrayWithInvalidUnaryElement = [+"x"];
32 | readonly arraySatisfies = [] satisfies number[];
: ^^^^^^^^^^^^^^
33 | readonly arrayNonNull = []!;
`----
x TS9012: Property must have an explicit type annotation with
| --isolatedDeclarations.
,-[33:12]
32 | readonly arraySatisfies = [] satisfies number[];
33 | readonly arrayNonNull = []!;
: ^^^^^^^^^^^^
34 | readonly invalidDirectUnary = +"x";
`----
x TS9012: Property must have an explicit type annotation with
| --isolatedDeclarations.
,-[34:12]
33 | readonly arrayNonNull = []!;
34 | readonly invalidDirectUnary = +"x";
: ^^^^^^^^^^^^^^^^^^
35 | readonly invalidTemplateLiteral = `x${n}`;
`----
x TS9012: Property must have an explicit type annotation with
| --isolatedDeclarations.
,-[35:12]
34 | readonly invalidDirectUnary = +"x";
35 | readonly invalidTemplateLiteral = `x${n}`;
: ^^^^^^^^^^^^^^^^^^^^^^
36 |
`----
```