Skip to content

Commit 2f06b62

Browse files
committed
feat: add support for set and map #181
1 parent 5d55c11 commit 2f06b62

File tree

3 files changed

+49
-16
lines changed

3 files changed

+49
-16
lines changed

examples/json/data.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,11 @@ greatZoo.coordinates = {
254254
z: data.zoos[0].coordinates[2]
255255
};
256256
greatZoo.country = data.zoos[0].country;
257-
greatZoo.employees = [bob, mikasa, red, fried];
257+
greatZoo.employees = new Set([bob, mikasa, red, fried]);
258258
greatZoo.id = data.zoos[0].id;
259259
greatZoo.mascot = bagheera;
260260
greatZoo.name = data.zoos[0].name;
261-
greatZoo.unknownAnimals = { '1': unknownAnimal };
261+
greatZoo.unknownAnimals = new Map([['1', unknownAnimal]]);
262262
greatZoo.phoneBook = {
263263
'1': new PhoneNumber(data.zoos[0].phoneBook['1'].value),
264264
'2': new PhoneNumber(data.zoos[0].phoneBook['2'].value),
@@ -275,11 +275,11 @@ zooZoo.coordinates = {
275275
z: data.zoos[1].coordinates[2]
276276
};
277277
zooZoo.country = data.zoos[1].country;
278-
zooZoo.employees = [];
278+
zooZoo.employees = new Set([]);
279279
zooZoo.id = data.zoos[1].id;
280280
zooZoo.mascot = data.zoos[1].mascot;
281281
zooZoo.name = data.zoos[1].name;
282-
zooZoo.unknownAnimals = {};
282+
zooZoo.unknownAnimals = new Map();
283283

284284
const elonMusk = new Human(
285285
data.mainShareholder.name,

examples/models/zoo.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { JsonProperty, JsonObject } from '../../src';
1+
import { JsonObject, JsonProperty } from '../../src';
22

33
import { Animal } from './animal';
44
import { Employee } from './employee';
@@ -39,7 +39,7 @@ export class Zoo {
3939
@JsonProperty()
4040
description: string;
4141
@JsonProperty({ type: Employee })
42-
employees: Array<Employee>;
42+
employees: Set<Employee>;
4343
@JsonProperty()
4444
id: number;
4545
@JsonProperty()
@@ -48,8 +48,8 @@ export class Zoo {
4848
animals: Array<Animal>;
4949
@JsonProperty({ type: snakeOrPanther })
5050
mascot: Panther | Snake;
51-
@JsonProperty({ isDictionary: true, type: UnknownAnimal })
52-
unknownAnimals: { [id: string]: UnknownAnimal };
51+
@JsonProperty({ type: UnknownAnimal })
52+
unknownAnimals: Map<string, UnknownAnimal>;
5353
@JsonProperty({
5454
isDictionary: true,
5555
type: phoneNumberType

src/json-serializer.ts

+41-8
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,10 @@ export class JsonSerializer {
297297
}
298298

299299
const type = Reflection.getType(instance, propertyKey);
300-
const isArrayProperty = type?.name?.toLowerCase() === 'array';
300+
const typeName = type?.name?.toLowerCase();
301+
const isArrayProperty = typeName === 'array';
302+
const isSetProperty = typeName === 'set';
303+
const isMapProperty = typeName === 'map';
301304
let propertyType = metadata.type || type;
302305

303306
if (metadata.beforeDeserialize) {
@@ -307,10 +310,18 @@ export class JsonSerializer {
307310
let property: any;
308311
const predicate = metadata.predicate;
309312

310-
if (metadata.isDictionary) {
313+
if (metadata.isDictionary || isMapProperty) {
311314
property = this.deserializeDictionary(dataSource, propertyType, predicate);
312-
} else if (isArrayProperty) {
315+
316+
if (isMapProperty) {
317+
property = new Map(Object.entries(property));
318+
}
319+
} else if (isArrayProperty || isSetProperty) {
313320
property = this.deserializeArray(dataSource, propertyType, predicate);
321+
322+
if (isSetProperty) {
323+
property = new Set(property);
324+
}
314325
} else if (
315326
(!isJsonObject(propertyType) && !predicate) ||
316327
(predicate && !predicate(dataSource, obj))
@@ -550,18 +561,40 @@ export class JsonSerializer {
550561
private serializeProperty(instance: object, key: string, metadata: JsonPropertyMetadata): any {
551562
const property = instance[key];
552563
const type = Reflection.getType(instance, key);
553-
const isArrayProperty = type?.name?.toLocaleLowerCase() === 'array';
564+
const typeName = type?.name?.toLowerCase();
565+
const isArrayProperty = typeName === 'array';
566+
const isSetProperty = typeName === 'set';
567+
const isMapProperty = typeName === 'map';
554568
const predicate = metadata.predicate;
555569
const propertyType = metadata.type || type;
556570
const isJsonObjectProperty = isJsonObject(propertyType);
557571

558572
if (property && (isJsonObjectProperty || predicate)) {
559-
if (isArrayProperty) {
560-
return this.serializeObjectArray(property);
573+
if (isArrayProperty || isSetProperty) {
574+
const array = isSetProperty ? Array.from(property) : property;
575+
return this.serializeObjectArray(array);
561576
}
562577

563-
if (metadata.isDictionary) {
564-
return this.serializeDictionary(property);
578+
if (metadata.isDictionary || isMapProperty) {
579+
if (!isMapProperty) {
580+
return this.serializeDictionary(property);
581+
}
582+
583+
const obj = {};
584+
property.forEach((value, mapKey) => {
585+
if (isString(mapKey)) {
586+
obj[mapKey] = value;
587+
} else {
588+
this.error(
589+
`Fail to serialize: type of '${typeof mapKey}' is not assignable to type 'string'.\nReceived: ${JSON.stringify(
590+
mapKey
591+
)}.`
592+
);
593+
}
594+
});
595+
596+
console.log(obj);
597+
return this.serializeDictionary(obj);
565598
}
566599

567600
return this.serializeObject(property);

0 commit comments

Comments
 (0)