swc: Class transformer not working with swc
Describe the bug
When applying the plainToClass
function to a class defined with class-validator
, it returns the class with no attributes
Input code
Here is a repo with a test reproducing the error
const usersOptionsInput = plainToClass(GetUsersOptionsInput, {
query: "Query",
pagination: { skip: 0, limit: 20 },
});
expect(usersOptionsInput.query).toEqual("Query"); // error
Config
You can also find the config at the repo reproducing the error
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"target": "es2018"
},
"module": {
"type": "commonjs",
"noInterop": true
}
}
Expected behavior I would expect the instance of the class to have all the defined attributes.
Version The version of @swc/core: 1.2.80
Additional context
Just one more time, I created this repo in order to reproduce the error
This error is related to #1362
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 15
- Comments: 16 (2 by maintainers)
@tonivj5 Thank you so much for that workaround!
@kdy1 Fixing this would make a world of difference for anyone part of the Nest.js community, it’d be hugely appreciated!
I investigated this.
For the
initializer
property of the property descriptor for fields without an initializer, babel usesnull
while swc emitsvoid 0
._applyDecoratedDescriptor
returnsnull
ifinitializer
isundefined
, so the property descriptor used for_initializerDefineProperty
while instantiating a class is an object for babel while beingnull
for swc.https://github.com/babel/babel/blob/69ae3b5a250d60618702751aa2aa4f56ccd43988/packages/babel-plugin-proposal-decorators/src/transformer-legacy.ts#L146-L152
I tried changing the value to
null
, but it broke other tests. Namely, the tests I added for https://github.com/swc-project/swc/issues/2127 in https://github.com/swc-project/swc/pull/3105 was problematic.I decided to postpone this.
@kdy1 yep! It doesn’t work.
This code does not work:
This code does work:
I did a deeper research here https://github.com/swc-project/swc/issues/2117#issuecomment-906681274
this is blocking for us to migrate to swc, company wide
I’ve been checking the generated code, and there’s a problematic part.
Minimal repro
This is the problematic part from
_applyDecoratedDescriptor
, this branch is executed byinitializer: void 0
When the property decorated has not
initializer
the descriptor decorator returned isnull
. If we remove thatif
, the repro code works and tests pass.I don’t know exactly why that check is neccesary, but there is the problem.
I hope it helps @kdy1! Excellent project btw 🆙
There is also a similar issue when upgrading to Next js 12, they use SWC and support legacy decorators but the @expose() and @exclude() decorators also seem to be falling. they return undefined attributes.
Issue on
class-transformer
side https://github.com/typestack/class-transformer/issues/796 I suppose invalid, and it should be fixed in swc.Great work @tonivj5! i tried diving into the generated code but I didn’t reach any conclusions, thanks for your insight!
Coming from: https://stackoverflow.com/questions/70956406/plaintoclass-from-class-transform-converts-incorrecly Any progress or possible workaround on this issue? Tried to use
esbuild
andplainToClass
method works correctly.If you’re struggling with this issue here is the way to fix it so it’s almost 0 pain while we’re waiting for fix. https://github.com/nestjs/nest-cli/issues/731#issuecomment-993936178