mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(isolated-declarations): emit const readonly fields as types (#24288)
## Summary Fixes #24284. TypeScript 6.0.3 emits bare readonly literal class fields as value initializers, but emits readonly `as const` literal fields as type annotations. Oxc previously unwrapped `as const` in the readonly class-property initializer path, so `static readonly A = "a" as const` became `static readonly A = "a";` instead of `static readonly A: "a";`. This changes the readonly class-property handling to preserve value initializers only for bare literals. Const assertions now flow through the existing const-expression type conversion.
This commit is contained in:
1 parent
042222fbe5
commit
f17514b21c
4 files changed
+41
-14
No files matched your search
@@ -105,8 +105,10 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
type_annotation = property.type_annotation.clone_in(self.allocator());
|
||||
} else if let Some(expr) = property.value.as_ref() {
|
||||
let ts_type = if property.readonly {
|
||||
// Keep literal const initializers on readonly class properties to match TS d.ts emit.
|
||||
if let Some(initializer) = self.get_literal_const_initializer(expr) {
|
||||
// Keep literal initializers without const assertions to match TS d.ts emit.
|
||||
if let Some(initializer) =
|
||||
self.get_literal_initializer_without_const_assertion(expr)
|
||||
{
|
||||
value = Some(initializer);
|
||||
None
|
||||
} else if Self::is_non_const_array_literal(expr) {
|
||||
@@ -146,7 +148,10 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
fn get_literal_const_initializer(&self, expr: &Expression<'a>) -> Option<Expression<'a>> {
|
||||
fn get_literal_initializer_without_const_assertion(
|
||||
&self,
|
||||
expr: &Expression<'a>,
|
||||
) -> Option<Expression<'a>> {
|
||||
match expr {
|
||||
Expression::BooleanLiteral(_)
|
||||
| Expression::NumericLiteral(_)
|
||||
@@ -159,13 +164,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||
Some(Expression::UnaryExpression(expr.clone_in(self.allocator())))
|
||||
}
|
||||
Expression::ParenthesizedExpression(expr) => {
|
||||
self.get_literal_const_initializer(&expr.expression)
|
||||
}
|
||||
Expression::TSAsExpression(expr) if expr.type_annotation.is_const_type_reference() => {
|
||||
self.get_literal_const_initializer(&expr.expression)
|
||||
}
|
||||
Expression::TSTypeAssertion(expr) if expr.type_annotation.is_const_type_reference() => {
|
||||
self.get_literal_const_initializer(&expr.expression)
|
||||
self.get_literal_initializer_without_const_assertion(&expr.expression)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export class C {
|
||||
readonly instanceBare = "i";
|
||||
readonly instanceConst = "ic" as const;
|
||||
static readonly staticBare = "s";
|
||||
static readonly staticConst = "sc" as const;
|
||||
static readonly A = "a" as const;
|
||||
static readonly B: "b" = "b";
|
||||
static D = "d" as const;
|
||||
}
|
||||
|
||||
export const bare = "e" as const;
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
source: crates/oxc_isolated_declarations/tests/mod.rs
|
||||
input_file: crates/oxc_isolated_declarations/tests/fixtures/issue-24284.ts
|
||||
---
|
||||
```
|
||||
==================== .D.TS ====================
|
||||
|
||||
export declare class C {
|
||||
readonly instanceBare = "i";
|
||||
readonly instanceConst: "ic";
|
||||
static readonly staticBare = "s";
|
||||
static readonly staticConst: "sc";
|
||||
static readonly A: "a";
|
||||
static readonly B: "b";
|
||||
static D: "d";
|
||||
}
|
||||
export declare const bare: "e";
|
||||
+4
-4
@@ -8,15 +8,15 @@ input_file: crates/oxc_isolated_declarations/tests/fixtures/readonly-class-prope
|
||||
export declare class ReadonlyLiteralInitializers {
|
||||
readonly directTrue = true;
|
||||
readonly parenTrue = true;
|
||||
readonly constAssertTrue = true;
|
||||
readonly nestedConstAssert = true;
|
||||
readonly constAssertTrue: true;
|
||||
readonly nestedConstAssert: true;
|
||||
readonly directString = "x";
|
||||
readonly parenString = "x";
|
||||
readonly templateNoExpr = "x";
|
||||
readonly constAssertString = "x";
|
||||
readonly constAssertString: "x";
|
||||
readonly unaryNumber = -1;
|
||||
readonly unaryParenNumber = -1;
|
||||
readonly constAssertNumber = 1;
|
||||
readonly constAssertNumber: 1;
|
||||
readonly directObject: {
|
||||
a: number;
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user