Skip to content

Commit 630484f

Browse files
delino[bot]github-actions[bot]claudekdy1
authored
fix(es/decorators): Emit correct metadata for enum parameters (#11154)
## Summary Fixes decorator metadata emission to correctly handle enum parameters in decorated methods and constructors. Previously, SWC incorrectly emitted `typeof Options === "undefined" ? Object : Options` for enum parameters, but it should emit: - `Number` for numeric enums - `String` for string enums - `Object` for mixed enums This matches TypeScript's behavior with `emitDecoratorMetadata`. ## Changes - Updated `visit_mut_class_method` in `metadata.rs` to check the enum map before serializing parameter types - Updated `visit_mut_class` in `metadata.rs` to check the enum map for constructor parameters - Added test case for issue #11032 demonstrating the fix ## Root Cause The bug was an inconsistency in how parameter types were handled vs. return types and property types: - Return types and property types correctly checked `self.enums.get_kind_as_str()` before calling `serialize_type()` - Parameter types (both in methods and constructors) did NOT check the enum map The fix applies the same pattern used for return types to parameter types as well. ## Test Plan - [x] Added new test case in `tests/fixture/legacy-metadata/issues/11032/1/` - [x] All existing legacy-metadata tests pass - [x] New test verifies that numeric enum parameters emit `Number` instead of the typeof check - [x] Code formatted with `cargo fmt --all` ## Related Issue Fixes #11032 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Donny/강동윤 <kdy.1997.dev@gmail.com>
1 parent c2e75f3 commit 630484f

File tree

4 files changed

+54
-9
lines changed

4 files changed

+54
-9
lines changed

.changeset/tough-fireants-float.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
swc_ecma_transforms_proposal: swc_core
3+
swc_ecma_transforms_proposal: patch
4+
---
5+
6+
fix(decorators): Emit correct metadata for enum parameters
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
enum Options {
2+
foo = 0
3+
}
4+
5+
function decorate() {
6+
return function() {}
7+
}
8+
9+
class Foo {
10+
@decorate()
11+
foo(options: Options) {}
12+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
enum Options {
2+
foo = 0
3+
}
4+
function decorate() {
5+
return function() {};
6+
}
7+
class Foo {
8+
foo(options: Options) {}
9+
}
10+
_ts_decorate([
11+
decorate(),
12+
_ts_metadata("design:type", Function),
13+
_ts_metadata("design:paramtypes", [
14+
Number
15+
]),
16+
_ts_metadata("design:returntype", void 0)
17+
], Foo.prototype, "foo", null);

crates/swc_ecma_transforms_proposal/src/decorators/legacy/metadata.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,20 @@ impl VisitMut for Metadata<'_> {
175175
#[cfg(swc_ast_unknown)]
176176
_ => panic!("unable to access unknown nodes"),
177177
};
178-
Some(serialize_type(self.class_name, ann).as_arg())
178+
Some(if let Some(kind) = self.enums.get_kind_as_str(ann) {
179+
quote_ident!(kind).as_arg()
180+
} else {
181+
serialize_type(self.class_name, ann).as_arg()
182+
})
183+
}
184+
ParamOrTsParamProp::Param(p) => {
185+
let param_type = get_type_ann_of_pat(&p.pat);
186+
Some(if let Some(kind) = self.enums.get_kind_as_str(param_type) {
187+
quote_ident!(kind).as_arg()
188+
} else {
189+
serialize_type(self.class_name, param_type).as_arg()
190+
})
179191
}
180-
ParamOrTsParamProp::Param(p) => Some(
181-
serialize_type(self.class_name, get_type_ann_of_pat(&p.pat))
182-
.as_arg(),
183-
),
184192
#[cfg(swc_ast_unknown)]
185193
_ => panic!("unable to access unknown nodes"),
186194
})
@@ -231,10 +239,12 @@ impl VisitMut for Metadata<'_> {
231239
.params
232240
.iter()
233241
.map(|v| {
234-
Some(
235-
serialize_type(self.class_name, get_type_ann_of_pat(&v.pat))
236-
.as_arg(),
237-
)
242+
let param_type = get_type_ann_of_pat(&v.pat);
243+
Some(if let Some(kind) = self.enums.get_kind_as_str(param_type) {
244+
quote_ident!(kind).as_arg()
245+
} else {
246+
serialize_type(self.class_name, param_type).as_arg()
247+
})
238248
})
239249
.collect(),
240250
}

0 commit comments

Comments
 (0)