diff --git a/crates/swc_ecma_transforms_typescript/src/config.rs b/crates/swc_ecma_transforms_typescript/src/config.rs index 6939b0efc385..e93d9a99b887 100644 --- a/crates/swc_ecma_transforms_typescript/src/config.rs +++ b/crates/swc_ecma_transforms_typescript/src/config.rs @@ -18,6 +18,14 @@ pub struct Config { #[serde(default)] pub import_export_assign_config: TsImportExportAssignConfig, + + /// Disables an optimization that inlines TS enum member values + /// within the same module that assumes the enum member values + /// are never modified. + /// + /// Defaults to false. + #[serde(default)] + pub ts_enum_is_mutable: bool, } #[derive(Debug, Default, Serialize, Deserialize)] diff --git a/crates/swc_ecma_transforms_typescript/src/transform.rs b/crates/swc_ecma_transforms_typescript/src/transform.rs index 37b8455c4121..568999a5350d 100644 --- a/crates/swc_ecma_transforms_typescript/src/transform.rs +++ b/crates/swc_ecma_transforms_typescript/src/transform.rs @@ -51,6 +51,7 @@ pub(crate) struct Transform { top_level_ctxt: SyntaxContext, import_export_assign_config: TsImportExportAssignConfig, + ts_enum_is_mutable: bool, verbatim_module_syntax: bool, namespace_id: Option, @@ -64,12 +65,14 @@ pub(crate) struct Transform { pub fn transform( top_level_mark: Mark, import_export_assign_config: TsImportExportAssignConfig, + ts_enum_is_mutable: bool, verbatim_module_syntax: bool, ) -> impl Fold + VisitMut { as_folder(Transform { top_level_mark, top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark), import_export_assign_config, + ts_enum_is_mutable, verbatim_module_syntax, ..Default::default() }) @@ -81,13 +84,10 @@ impl VisitMut for Transform { fn visit_mut_program(&mut self, n: &mut Program) { n.visit_mut_children_with(self); - if self.record.is_empty() { - return; + if !self.ts_enum_is_mutable && !self.record.is_empty() { + let record = mem::take(&mut self.record); + n.visit_mut_children_with(&mut InlineEnum::new(record)); } - - let record = mem::take(&mut self.record); - - n.visit_mut_children_with(&mut InlineEnum::new(record)); } fn visit_mut_module_items(&mut self, n: &mut Vec) { diff --git a/crates/swc_ecma_transforms_typescript/src/typescript.rs b/crates/swc_ecma_transforms_typescript/src/typescript.rs index 0e3296d27349..dc6fc07cd416 100644 --- a/crates/swc_ecma_transforms_typescript/src/typescript.rs +++ b/crates/swc_ecma_transforms_typescript/src/typescript.rs @@ -46,6 +46,7 @@ impl VisitMut for TypeScript { n.visit_mut_with(&mut transform( self.top_level_mark, self.config.import_export_assign_config, + self.config.ts_enum_is_mutable, self.config.verbatim_module_syntax, )); diff --git a/crates/swc_ecma_transforms_typescript/tests/strip.rs b/crates/swc_ecma_transforms_typescript/tests/strip.rs index 6c8b564bd296..43ab4caa60b5 100644 --- a/crates/swc_ecma_transforms_typescript/tests/strip.rs +++ b/crates/swc_ecma_transforms_typescript/tests/strip.rs @@ -4552,3 +4552,34 @@ test!( } " ); + +test!( + Syntax::Typescript(TsConfig::default()), + |_| tr_config( + Some(typescript::Config { + ts_enum_is_mutable: true, + ..Default::default() + }), + None, + true, + ), + ts_enum_is_mutable_true, + r#" + enum D { + A, + B, + } + + (D as any).A = 5; + console.log(D.A); + "#, + r#" + var D; + (function(D) { + D[D["A"] = 0] = "A"; + D[D["B"] = 1] = "B"; + })(D || (D = {})); + D.A = 5; + console.log(D.A); + "# +);