Skip to content

Commit 4b3e726

Browse files
fix: write properties with defined default values on prototype
2 parents c3ced62 + 5ff2c68 commit 4b3e726

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

src/TransformOperationExecutor.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,17 @@ export class TransformOperationExecutor {
170170
if (metadata.options && metadata.options.discriminator && metadata.options.discriminator.property && metadata.options.discriminator.subTypes) {
171171
if (!(value[valueKey] instanceof Array)) {
172172
if (this.transformationType === TransformationType.PLAIN_TO_CLASS) {
173-
type = metadata.options.discriminator.subTypes.find((subType) => subType.name === subValue[metadata.options.discriminator.property]);
173+
type = metadata.options.discriminator.subTypes.find((subType) => {
174+
if (subValue && metadata.options.discriminator.property in subValue) {
175+
return subType.name === subValue[metadata.options.discriminator.property]
176+
}
177+
});
174178
type === undefined ? type = newType : type = type.value;
175-
if (!metadata.options.keepDiscriminatorProperty) delete subValue[metadata.options.discriminator.property];
179+
if (!metadata.options.keepDiscriminatorProperty) {
180+
if (subValue && metadata.options.discriminator.property in subValue) {
181+
delete subValue[metadata.options.discriminator.property];
182+
}
183+
}
176184
}
177185
if (this.transformationType === TransformationType.CLASS_TO_CLASS) {
178186
type = subValue.constructor;
@@ -217,7 +225,7 @@ export class TransformOperationExecutor {
217225
if (newValue.constructor.prototype) {
218226
const descriptor = Object.getOwnPropertyDescriptor(newValue.constructor.prototype, newValueKey);
219227
if ((this.transformationType === TransformationType.PLAIN_TO_CLASS || this.transformationType === TransformationType.CLASS_TO_CLASS)
220-
&& ((descriptor && !descriptor.set) || newValue[newValueKey] instanceof Function)) // || TransformationType === TransformationType.CLASS_TO_CLASS
228+
&& ((descriptor && !descriptor.writable) || newValue[newValueKey] instanceof Function)) // || TransformationType === TransformationType.CLASS_TO_CLASS
221229
continue;
222230
}
223231

test/functional/serialization-deserialization.spec.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,46 @@ describe("serialization and deserialization objects", () => {
107107
// (<any>result).extra.should.be.undefined;
108108
});
109109

110-
});
110+
111+
it("should not overwrite non writable properties on deserialize", () => {
112+
class TestObject {
113+
get getterOnlyProp(): string {
114+
return "I cannot write!";
115+
}
116+
117+
normalProp: string = "Hello!";
118+
}
119+
120+
const payload = {
121+
getterOnlyProp: "I CAN write!",
122+
normalProp: "Goodbye!"
123+
};
124+
125+
const result = deserialize(TestObject, JSON.stringify(payload));
126+
127+
result.getterOnlyProp.should.be.eql("I cannot write!");
128+
result.normalProp.should.be.eql("Goodbye!");
129+
130+
});
131+
132+
it("should overwrite default properties defined in prototype", () => {
133+
class TestObject {
134+
normalProp: string = "Hello!";
135+
prototypedProp: string;
136+
}
137+
138+
TestObject.prototype.prototypedProp = "I'm a BUG!";
139+
140+
141+
const payload = {
142+
normalProp: "Goodbye!",
143+
prototypedProp: "Goodbye!"
144+
};
145+
146+
const result = deserialize(TestObject, JSON.stringify(payload));
147+
148+
result.normalProp.should.be.eql("Goodbye!");
149+
result.prototypedProp.should.be.eql("Goodbye!");
150+
});
151+
152+
});

0 commit comments

Comments
 (0)