mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(isolated-declarations): align readonly class array initializer diagnostics with tsc (#19218)
This commit is contained in:
1 parent
3ea8f08364
commit
3e0e5ba49f
5 files changed
+335
-13
No files matched your search
@@ -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>,
|
||||
|
||||
+12
@@ -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];
|
||||
}
|
||||
+41
@@ -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}`];
|
||||
}
|
||||
+47
-1
@@ -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];
|
||||
`----
|
||||
|
||||
|
||||
```
|
||||
+218
@@ -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 |
|
||||
`----
|
||||
|
||||
|
||||
```
|
||||
Reference in new issue
Block a user