fix(isolated-declarations): preserve readonly literal initializers (#19177)

This is the cause of the current monitor oxc failure

TS's Behaviour:

![Screenshot 2026-02-09 at 12.18.51.png](https://app.graphite.com/user-attachments/assets/858f029d-5427-4593-95c1-ae5efd3239e1.png)

Us Before:

![Screenshot 2026-02-09 at 12.18.17.png](https://app.graphite.com/user-attachments/assets/a4df3235-e4cd-4526-b632-df7371181922.png)

Us After:

```
export declare class ReadonlyLiteralInitializers {

	readonly directTrue = true;
	readonly constAssertTrue = true;
	writableTrue: boolean;
}
```
This commit is contained in:
camc314 committed 2026-02-10 02:06:13 +00:00
1 parent d0ca8d0077
commit 312e7565e2
5 files changed
+96 -2

No files matched your search

+30 -2
View File
@@ -104,8 +104,11 @@ impl<'a> IsolatedDeclarations<'a> {
type_annotation = property.type_annotation.clone_in(self.ast.allocator);
} else if let Some(expr) = property.value.as_ref() {
let ts_type = if property.readonly {
// `field = 'string'` remain `field = 'string'` instead of `field: 'string'`
if Self::is_need_to_infer_type_from_expression(expr) {
// Keep literal const initializers on readonly class properties to match TS d.ts emit.
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 let Expression::TemplateLiteral(lit) = expr {
@@ -147,6 +150,31 @@ impl<'a> IsolatedDeclarations<'a> {
)
}
fn get_literal_const_initializer(&self, expr: &Expression<'a>) -> Option<Expression<'a>> {
match expr {
Expression::BooleanLiteral(_)
| Expression::NumericLiteral(_)
| Expression::BigIntLiteral(_)
| Expression::StringLiteral(_) => Some(expr.clone_in(self.ast.allocator)),
Expression::TemplateLiteral(lit) if lit.expressions.is_empty() => {
self.transform_template_to_string(lit).map(Expression::StringLiteral)
}
Expression::UnaryExpression(expr) if Self::can_infer_unary_expression(expr) => {
Some(Expression::UnaryExpression(expr.clone_in(self.ast.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)
}
_ => None,
}
}
fn transform_class_method_definition(
&self,
definition: &MethodDefinition<'a>,
@@ -0,0 +1,17 @@
export class ReadonlyLiteralInitializers {
readonly directTrue = true;
readonly parenTrue = (true);
readonly constAssertTrue = true as const;
readonly nestedConstAssert = ((true as const));
readonly directString = "x";
readonly parenString = ("x");
readonly templateNoExpr = `x`;
readonly constAssertString = ("x" as const);
readonly unaryNumber = -1;
readonly unaryParenNumber = (-1);
readonly constAssertNumber = (1 as const);
writableTrue = true;
}
@@ -0,0 +1,3 @@
export class ReadonlySatisfies {
readonly falseSatisfies = (false satisfies boolean);
}
@@ -0,0 +1,21 @@
---
source: crates/oxc_isolated_declarations/tests/mod.rs
input_file: crates/oxc_isolated_declarations/tests/fixtures/readonly-class-property-initializer.ts
---
```
==================== .D.TS ====================
export declare class ReadonlyLiteralInitializers {
readonly directTrue = true;
readonly parenTrue = true;
readonly constAssertTrue = true;
readonly nestedConstAssert = true;
readonly directString = "x";
readonly parenString = "x";
readonly templateNoExpr = "x";
readonly constAssertString = "x";
readonly unaryNumber = -1;
readonly unaryParenNumber = -1;
readonly constAssertNumber = 1;
writableTrue: boolean;
}
@@ -0,0 +1,25 @@
---
source: crates/oxc_isolated_declarations/tests/mod.rs
input_file: crates/oxc_isolated_declarations/tests/fixtures/readonly-satisfies.ts
---
```
==================== .D.TS ====================
export declare class ReadonlySatisfies {
readonly falseSatisfies;
}
==================== Errors ====================
x TS9012: Property must have an explicit type annotation with
| --isolatedDeclarations.
,-[2:12]
1 | export class ReadonlySatisfies {
2 | readonly falseSatisfies = (false satisfies boolean);
: ^^^^^^^^^^^^^^
3 | }
`----
```