Getting Started
Serialazy is a serialization / data-mapping library which can be used to deflate/inflate TypeScript class instances as well as plain JS objects (POJO).
Features:
- Default serializers for primitive types (string, number, boolean)
- Support for optional, nullable and mapped properties
- Recursive serialization for nested data structures
- Property serializers inheritance (from parent class to a child)
- User defined serialization functions for properties and types
- Alternative projections
- Async serialization
- TypeScript-friendly API based on decorators
âš Note: Version 3.x.x introduces breaking changes compared to 2.x.x.
Requirements
Library makes use of TypeScript experimental feature which emits type metadata to the resulting JS.
Make sure that you enabled experimentalDecorators
and emitDecoratorMetadata
in your tsconfig.json
.
Installation
npm i --save serialazy
Basic usage
import { deflate, inflate } from 'serialazy';
const serialized = deflate(serializable);
const deserialized = inflate(SerializableType, serialized);
Where:
serialized
is a JSON-compatible value which can be safely passed toJSON.stringify
SerializableType
is a constructor function for serializable typeserializable
is a primitive (string, number, boolean or their "boxed" variants, null, undefined), or a non-primitive serializable
There are 2 types of non-primitive serializables:
1. A type with custom serializer
Is a TS class decorated with @Serialize()
.
import { Serialize } from 'serialazy';
// Position class serializes to a tuple: [number, number]
@Serialize({
down: (pos: Position) => [pos.x, pos.y],
up: (tuple) => Object.assign(new Position(), { x: tuple[0], y: tuple[1] })
})
class Position {
public x: number;
public y: number;
}
2. A "property bag"
Is a TS class having properties decorated with @Serialize()
.
- Always serializes to a plain object
- Can extend (inherit from) another property bag
import { Serialize } from 'serialazy';
// Shape is a "property bag" serializable
class Shape {
@Serialize() public name: string;
}
// Sphere inherits property serializers from Shape
class Sphere extends Shape {
@Serialize() public radius: number;
@Serialize() public position: Position;
}
Above classes can be serialized / deserialized like this:
import { deflate, inflate } from 'serialazy';
import chai = require('chai');
const { expect } = chai;
const sphere = Object.assign(new Sphere(), {
name: 'sphere1',
radius: 10,
position: Object.assign(new Position(), {
x: 3,
y: 5
})
});
const serialized = deflate(sphere);
expect(serialized).to.deep.equal({
name: 'sphere1',
radius: 10,
position: [3, 5]
});
const deserialized = inflate(Sphere, serialized);
// Deserialized sphere should be identical with the original one
expect(deserialized).to.deep.equal(sphere);
Serializable base class
Library provides an optional abstract base class for serializables.
Currently it only provides static factory method create
which makes instance creation more compact
and type-safe. Above example could look like this:
import { Serializable, Serialize } from 'serialazy';
@Serialize({ ... })
class Position extends Serializable { ... }
class Shape extends Serializable { ... }
class Sphere extends Shape { ... }
const sphere = Sphere.create({
name: 'sphere1',
radius: 10,
position: Position.create({ x:3, y: 5 })
});
...