Skip to content

Commit 5c31236

Browse files
committed
fix(isolated-declarations): keep literal value for readonly property (#4106)
close: #4036
1 parent e67c7d1 commit 5c31236

File tree

2 files changed

+33
-29
lines changed

2 files changed

+33
-29
lines changed

crates/oxc_isolated_declarations/src/class.rs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,40 +54,44 @@ impl<'a> IsolatedDeclarations<'a> {
5454
&self,
5555
property: &PropertyDefinition<'a>,
5656
) -> ClassElement<'a> {
57-
let type_annotations = if property.accessibility.is_some_and(|a| a.is_private()) {
58-
None
59-
} else {
60-
property
61-
.type_annotation
62-
.as_ref()
63-
.map(|type_annotation| self.ast.copy(type_annotation))
64-
.or_else(|| {
65-
property
66-
.value
67-
.as_ref()
68-
.and_then(|expr| {
69-
let ts_type = if property.readonly {
70-
self.transform_expression_to_ts_type(expr)
71-
} else {
72-
self.infer_type_from_expression(expr)
73-
};
74-
if ts_type.is_none() {
75-
self.error(property_must_have_explicit_type(property.key.span()));
76-
}
77-
ts_type
78-
})
79-
.map(|ts_type| self.ast.ts_type_annotation(SPAN, ts_type))
80-
})
81-
};
57+
let mut type_annotations = None;
58+
let mut value = None;
59+
60+
if property.accessibility.map_or(true, |a| !a.is_private()) {
61+
if property.type_annotation.is_some() {
62+
type_annotations = self.ast.copy(&property.type_annotation);
63+
} else if let Some(expr) = property.value.as_ref() {
64+
let ts_type = if property.readonly {
65+
// `field = 'string'` remain `field = 'string'` instead of `field: 'string'`
66+
if Self::is_need_to_infer_type_from_expression(expr) {
67+
self.transform_expression_to_ts_type(expr)
68+
} else {
69+
if let Expression::TemplateLiteral(lit) = expr {
70+
value = self
71+
.transform_template_to_string(lit)
72+
.map(Expression::StringLiteral);
73+
} else {
74+
value = Some(self.ast.copy(expr));
75+
}
76+
None
77+
}
78+
} else {
79+
self.infer_type_from_expression(expr)
80+
};
8281

83-
// TODO if inferred type_annotations is TSLiteral, it should stand as value,
84-
// so `field = 'string'` remain `field = 'string'` instead of `field: 'string'`
82+
type_annotations = ts_type.map(|t| self.ast.ts_type_annotation(SPAN, t));
83+
}
84+
85+
if type_annotations.is_none() && value.is_none() {
86+
self.error(property_must_have_explicit_type(property.key.span()));
87+
}
88+
}
8589

8690
self.ast.class_property(
8791
property.r#type,
8892
property.span,
8993
self.ast.copy(&property.key),
90-
None,
94+
value,
9195
property.computed,
9296
property.r#static,
9397
property.declare,

crates/oxc_isolated_declarations/tests/snapshots/class.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export declare abstract class Qux {
2020
baz(): void;
2121
}
2222
export declare class Baz {
23-
readonly prop1: 'some string';
23+
readonly prop1 = 'some string';
2424
prop2: string;
2525
private prop3;
2626
private prop4;

0 commit comments

Comments
 (0)