mydomain
No ADS
No ADS

Parsing JSON in TypeScript with the json2typescript library

  1. json2typescript
  2. Install
  3. Basic example
  4. @JsonProperty
  5. @JsonConverter

1. json2typescript

json2typescript is a library that contains helper classes to define a mapping between a JSON document and a TypeScript object. This library is inspired by Java Jackson and has similar features.
Basically, json2typescript is suitable for large projects that require a few configuration steps. If you are only working with JSON in a small TypeScript project, consider using the JSON.parse(..) and JSON.stringify(..) methods, which are simple and do not require any additional configuration.

2. Install

No ADS
First, install the json2typescript library into the project:
npm install json2typescript
Next, add the following properties to the tsconfig.json file:
tsconfig.json
{
  "compilerOptions": {  
    ...
    "experimentalDecorators": true,
    "allowJs": true
  }
}

3. Basic example

No ADS
In this example, we will create 2 model files:
  • model_file1.ts
  • model_file2.ts.
Classes are defined in the model files. Use @JsonObject and @JsonProperty to annotate on the class and its properties to suggest to the tool how to convert TypeScript objects to JSON text and vice versa.
@JsonObject
A class is annotated with @JsonObject, then its object can be converted to a JSON text and vice versa.
@JsonProperty
A property of a TypeScript object can be converted to a property of JSON if it is annotated by @JsonProperty. Otherwise, it will be ignored.
All properties of the TypeScript class annotated by @JsonProperty must be set to default values. Otherwise, the result may not be what you expect.
model_file1.ts
import {
    JsonObject, JsonProperty, JsonConvert, OperationMode,
    ValueCheckingMode, PropertyConvertingMode
} from "json2typescript";

@JsonObject("Contact")
export class Contact {
    // PropertyConvertingMode.MAP_NULLABLE is default.
    // MAP_NULLABLE: Throw Exception if JSON value is undefined
    // IGNORE_NULLABLE: Using Java property default value if JSON value is undefined
    // PASS_NULLABLE: Set Java property value to null if JSON value is undefined
    @JsonProperty("address", String, PropertyConvertingMode.MAP_NULLABLE)
    address: string = '';
    @JsonProperty("phone", String, PropertyConvertingMode.MAP_NULLABLE)
    phone: string = '';
}
@JsonObject("Employee")
export class Employee {
    @JsonProperty("employeeName", String, PropertyConvertingMode.MAP_NULLABLE)
    name: string = '';
    @JsonProperty("email", String, PropertyConvertingMode.MAP_NULLABLE)
    email: string = '';
    @JsonProperty("contact", Contact, PropertyConvertingMode.PASS_NULLABLE)
    contact?: Contact = new Contact();
}
PropertyConvertingMode.MAP_NULLABLE:
This is the default conversion mode. An exception will be thrown if there is no JSON property corresponding to this property of the TypeScript class.
PropertyConvertingMode.IGNORE_NULLABLE:
Property of TypeScript object will get default value if there is no corresponding property in JSON.
PropertyConvertingMode.PASS_NULLABLE:
Property of TypeScript object will be null if there is no corresponding property in JSON.
model_file2.ts
import {
    JsonObject, JsonProperty, JsonConvert, OperationMode,
    ValueCheckingMode, PropertyConvertingMode
} from "json2typescript";

import { Contact } from './model_file1';

@JsonObject("Company")
class Company {
    @JsonProperty("companyName", String, PropertyConvertingMode.MAP_NULLABLE)
    name: string = '';
    @JsonProperty("contact", Contact, PropertyConvertingMode.PASS_NULLABLE)
    contact?: Contact = new Contact();
}
If you use Visual Studio Code to write code, you may get an error message like below. See how to fix the error shared on stackoverflow:
Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.ts(1219)
json2typescript_ex1.ts
import {
    JsonObject, JsonConvert, OperationMode, ValueCheckingMode
} from "json2typescript";

import { Employee, Contact } from './model_file1';

// @see Employee class in model_file1.ts
let jsonStr = `  {
    "employeeName": "John Smith",
    "email": "john@example.com",
    "contact": {
       "address": "Address 1",
       "phone": "12345"
    }
} `;
let jsonConvert: JsonConvert = new JsonConvert();

// ----------- JSON Text to TypeScript Object ------------------  
let jsonObj: any = JSON.parse(jsonStr);  
let emp: Employee = jsonConvert.deserializeObject(jsonObj, Employee);
console.log('JSON to TypeScript:');
console.log(emp);
console.log(' ------------- ');

// ----------- TypeScript Object to JSON Text ------------------
let jsonText = jsonConvert.serialize(emp);
console.log('TypeScript to JSON:');
console.log(jsonText);
Output:
JSON to TypeScript:
Employee {
  name: 'John Smith',
  email: 'john@example.com',
  contact: Contact { address: 'Address 1', phone: '12345' }
}
 -------------
TypeScript to JSON:
{
  employeeName: 'John Smith',
  email: 'john@example.com',
  contact: { address: 'Address 1', phone: '12345' }
}
json2typescript_ex2.ts
import {
    JsonObject, JsonConvert, OperationMode, ValueCheckingMode
} from "json2typescript";

import { Employee, Contact } from './model_file1';

// @see Employee class in model_file1.ts
let jsonStr = `  {
   "employeeName": "John Smith",
    "email": "john@example.com"
} `;
let jsonConvert: JsonConvert = new JsonConvert();

// ----------- JSON Text to TypeScript Object ------------------
let jsonObj: any = JSON.parse(jsonStr);  
let emp: Employee = jsonConvert.deserializeObject(jsonObj, Employee);
console.log('JSON to TypeScript:');
console.log(emp);
console.log(' ------------- ');

// ----------- TypeScript Object to JSON Text ------------------
let jsonText = jsonConvert.serialize(emp);
console.log('TypeScript to JSON:');
console.log(jsonText);
Output:
JSON to TypeScript:
Employee {
  name: 'John Smith',
  email: 'john@example.com',
  contact: undefined
}
-------------
TypeScript to JSON:
{
  employeeName: 'John Smith',
  email: 'john@example.com',
  contact: undefined
}

4. @JsonProperty

No ADS
A property of a TypeScript object can be converted to a property of JSON if it is annotated by @JsonProperty. Otherwise, it will be ignored.
All properties of the TypeScript class annotated by @JsonProperty must be set to default values. Otherwise, the result may not be what you expect.
Example:
// Model class:
@JsonObject("User")
export class User {
    @JsonProperty("userName", String, PropertyConvertingMode.MAP_NULLABLE)
    userName: string = '';
    @JsonProperty("joinDate", DateConverter)
    joinDate: Date = new Date();
}
Syntax:
@JsonProperty("JSON_Property_Name", JSON_Type, Custom_Converter, PropertyConvertingMode)
JSON_Property_Name
Name of property in JSON.
JSON_Type (Optional)
A JSON data type.
  • String, [String]
  • Number, [Number]
  • Boolean, [Boolean]
  • Any, [Any]
Custom_Converter (Optional)
See examples at @JsonConverter section.
PropertyConvertingMode (Optional)
PropertyConvertingMode.MAP_NULLABLE:
  • This is the default conversion mode. An exception will be thrown if there is no JSON property corresponding to this property of the TypeScript class.
PropertyConvertingMode.IGNORE_NULLABLE:
  • Property of TypeScript object will get default value if there is no corresponding property in JSON.
PropertyConvertingMode.PASS_NULLABLE:
  • Property of TypeScript object will be null if there is no corresponding property in JSON.

5. @JsonConverter

No ADS
In some cases, you may need to make custom conversion between JSON objects and TypeScript objects. You can define custom converters like this:
model_file3.ts
import {
    JsonObject, JsonProperty, JsonConvert, OperationMode,
    ValueCheckingMode, PropertyConvertingMode, JsonConverter, JsonCustomConvert
} from "json2typescript";
// Custom Converter:
@JsonConverter
class DateConverter implements JsonCustomConvert<Date> {
    serialize(date: Date): any {
        return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
    }
    deserialize(date: any): Date {
        return new Date(date);
    }
}
// Model class:
@JsonObject("User")
export class User {
    @JsonProperty("userName", String, PropertyConvertingMode.MAP_NULLABLE)
    userName: string = '';
    @JsonProperty("joinDate", DateConverter)
    joinDate: Date = new Date();
}
json2typescript_ex3.ts
import {
    JsonObject, JsonConvert, OperationMode, ValueCheckingMode
} from "json2typescript";

import { User  } from './model_file3';

// @see User class in model_file3.ts
let jsonStr = `  {
   "userName": "tom",
    "joinDate": "2021-12-15"
} `;
let jsonConvert: JsonConvert = new JsonConvert();

// ----------- JSON Text to TypeScript Object ------------------
let jsonObj: any = JSON.parse(jsonStr);  
let user: User = jsonConvert.deserializeObject(jsonObj, User);
console.log('JSON to TypeScript:');
console.log(user);
console.log(' ------------- ');

// ----------- TypeScript Object to JSON Text ------------------
let jsonText = jsonConvert.serialize(user);
console.log('TypeScript to JSON:');
console.log(jsonText);
Output:
JSON to TypeScript:
User { userName: 'tom', joinDate: 2021-12-15T00:00:00.000Z }
 -------------
TypeScript to JSON:
{ userName: 'tom', joinDate: '2021-12-15' }
No ADS
No ADS