class-transformer
class-transformer copied to clipboard
Adding @Alias decorator and allow multiple @Expose decorators
Description
Thank you for this amazing library 🚀
It has been discussed several times (sometimes with some confusion): in some scenarios, being able to rename a property only when importing or exporting it can be useful.
For instance, I am reading rows from a file in a format A sent by a third party, then convert it to an object in my TS code. It might be logged or stored in a file in another format B later on.
One of the field is named part_or_item_number
in the format A, which is then converted to partRef
in my JS object.
TLDR
plainToInstance
should accept this object:
{
"part_or_item_number": "part1234"
}
The property should be referenced as follow in the code:
findPart(myObj.partRef)
And instanceToPlain
should then produce the following:
{
"partRef": "part1234"
}
One would quickly suggest to use @Expose({ name: 'part_or_item_number' })
, however it would also expose the property under the name part_or_item_number
when using instanceToPlain
.
Adding the option toClassOnly: true
is not cutting it either as it would then hide the property when using instanceToPlain
.
Another suggestion seen in one of the thread linked earlier is to use two @Expose
:
...
@Expose({ name: 'part_or_item_number', toClassOnly: true })
@Expose({ toPlainOnly: true })
partRef: string;
...
While it's a pretty neat idea, it simply doesn't work in the current state, as the last @Expose
will always replace the previous ones.
This PR introduces two changes:
- Allow the previous sample of code to work as described
- Introduce an
Alias
decorator to reduce boilerplate in that scenario, using@Expose
behind the scene to reduce duplication
The code above could be rewritten as the following with the same expected behaviour:
...
@Alias({ from: 'part_or_item_number' })
partRef: string;
...
There is also a slight rewriting of the map manipulation code in MetadataStorage.ts
. I'm fine reverting it but it greatly improved the readability for me.
Checklist
- [x] the pull request title describes what this PR does (not a vague title like
Update index.md
) - [x] the pull request targets the default branch of the repository (
develop
) - [x] the code follows the established code style of the repository
-
npm run prettier:check
passes -
npm run lint:check
passes
-
- [x] tests are added for the changes I made (if any source code was modified)
- [x] documentation added or updated
- [x] I have run the project locally and verified that there are no errors
Fixes
fixes #677, fixes #121, fixes #366