ts-jackson
A typescript library to deserialize and serialize json into classes. You can use different path pattern
to resolve deeply nested structures. Every path pattern provided by lodash/get|set object is supported.
Check out src/examples for examples.
Installation
npm install ts-jackson --save
yarn add ts-jackson
For tsconfig.json file set experimentalDecorators and emitDecoratorMetadata to true to allow
support for the decorators:
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
import { JsonProperty, Serializable, deserialize, serialize } from 'typescript-json-serializer';
Api
Imports:
import { JsonProperty, Serializable, deserialize, serialize } from 'typescript-json-serializer';
Decorators
Serializable
To mark your class as serializable wrap your class with Serializable decorator:
@Serializable()
class Class {}
JsonProperty
type Params<P> = {
path?: string
required?: boolean
type?: new (...params: Array<unknown>) => unknown
elementType?: new (...params: Array<unknown>) => unknown
validate?: (property: P) => boolean
deserialize?: (jsonValue: unknown) => P
serialize?: (property: P) => unknown
}
@JsonProperty(options: Options | string)
path:
The path property can be set in a few different ways:
class Cat {
@JsonProperty()
name: string
}
class Track {
@JsonProperty('duration_ms')
durationMs: number
}
class Track {
@JsonProperty({
path: 'duration_ms'
})
durationMs: number
}
Path property supports different formats for resolving deeply nested structures provided by lodash `_.set(object, path, value)
Resolving deeply nested structures:
const trackJson = {
track: {
id: 'some id',
},
}
@Serializable()
class Track {
@JsonProperty('track.id')
readonly id: string
}
const deserialized = deserialize(trackJson, Track)
serialize(deserialized)
Resolving array structures
const jsonData = {
images: {
items: [
{
height: 300,
url:
'https://i.scdn.co/image/ab67616d0000b27380368f0aa8f90c51674f9dd2',
width: 300,
},
{
height: 640,
url:
'https://i.scdn.co/image/ab67616d00001e0280368f0aa8f90c51674f9dd2',
width: 640,
},
],
},
}
@Serializable()
class Playlist {
@JsonProperty('images.items[1]')
readonly backgroundImage: Image
}
const deserialized = deserialize(jsonData, Playlist)
const serialized = serialize(deserialized)
For more patterns for resolving structures check out lodash/get docs.
Functions
deserialize
export default function deserialize<T, U extends Array<unknown>>(
json: Record<string, unknown> | string,
serializableClass: new (...args: [...U]) => T,
...args: U
): T
serialize
export default function serialize<
T extends new (...args: unknown[]) => unknown
>(instance: InstanceType<T>): Record<string, unknown> {
Examples
const trackJson = {
track: {
id: 'some id',
},
}
@Serializable()
class Track {
@JsonProperty('track.id')
readonly id: string
}
const deserializedClassIntance = deserialize(trackJson, Track)
const serializedJson = serialize(deserializedClassIntance)
Using constructor arguments:
@Serializable()
class Image {
@JsonProperty({ required: true })
readonly url: string
constructor(readonly width: number, readonly height: number) {
}
}
deserialize({url: 'url'}, Image, 5, 3)
const deserializedClassIntance = deserialize({url: 'some url'}, Image, 5, 4)
const serializedJson = serialize(deserializedClassIntance)
SerializableEntity
class SerializableEntity {
serialize(): Record<string, unknown>;
static deserialize<T, U extends Array<unknown>>(this: {
new(...params: [...U]): T;
}, json: Record<string, unknown>, ...args: U): T;
}