Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

json2typescript

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

json2typescript - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0-rc.0

lib/cjs/index.d.ts

34

package.json
{
"name": "json2typescript",
"version": "1.4.1",
"version": "1.5.0-rc.0",
"description": "Provides TypeScript methods to map a JSON object to a JavaScript object on runtime",

@@ -20,8 +20,8 @@ "keywords": [

],
"author": "dhlab@unibas.ch",
"author": "AppVision GmbH",
"license": "MIT",
"homepage": "http://dhlab.unibas.ch",
"homepage": "https://appvision.ch",
"scripts": {
"test": "karma start karma.conf.js",
"build": "npm run test && tsc && npx downlevel-dts . ts3.4 && cp -r ts3.4/* . && rm -r ts3.4",
"build": "npm i && npm run test && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && npx downlevel-dts . ts3.4 && cp -r ts3.4/* . && rm -r ts3.4",
"dist": "npm run build && npm pack"

@@ -34,26 +34,22 @@ },

"devDependencies": {
"@types/jasmine": "^3.5.10",
"downlevel-dts": "^0.4.0",
"jasmine": "3.5.0",
"karma": "^5.0.1",
"@types/jasmine": "^3.8.1",
"downlevel-dts": "^0.7.0",
"jasmine": "3.8.0",
"karma": "^6.3.4",
"karma-chrome-launcher": "^3.1.0",
"karma-jasmine": "3.1.1",
"karma-jasmine": "4.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-typescript": "^5.0.2",
"karma-typescript": "^5.5.1",
"phantomjs-prebuilt": "^2.1.16",
"typescript": "3.8.3"
"typescript": "4.3.5"
},
"main": "index.js",
"main": "./lib/cjs/index.js",
"module": "./lib/esm/index.js",
"files": [
"src/json2typescript/*.d.ts",
"src/json2typescript/*.map",
"src/json2typescript/*.js",
"index.d.ts",
"index.js.map",
"index.js"
"lib/"
],
"repository": {
"type": "git",
"url": "https://github.com/dhlab-basel/json2typescript"
"url": "https://github.com/appvision-gmbh/json2typescript"
}
}

@@ -1,2 +0,2 @@

[![npm](https://img.shields.io/npm/v/json2typescript.svg)](https://www.npmjs.com/package/json2typescript)
[![npm](https://img.shields.io/npm/v/json2typescript.svg)](https://www.npmjs.com/package/json2typescript)
![](https://img.shields.io/npm/dt/json2typescript.svg?style=flat)

@@ -8,8 +8,9 @@ ![](https://img.shields.io/bundlephobia/minzip/json2typescript.svg?style=flat)

In Angular applications, everyone consumes JSON API's from an external source.
Type checking and object mapping is only possible in TypeScript, but not in the JavaScript runtime.
As the API may change at any point, it is important for larger projects to verify the consumed data.
In Angular applications, everyone consumes JSON API's from an external source. Type checking and object mapping is only
possible in TypeScript, but not in the JavaScript runtime. As the API may change at any point, it is important for
larger projects to verify the consumed data.
**json2typescript** is a small package containing a helper class that maps JSON objects to an instance of a TypeScript class.
After compiling to JavaScript, the result will still be an instance of this class. One big advantage of this approach is, that you can also use methods of this class.
**json2typescript** is a small package containing a helper class that maps JSON objects to an instance of a TypeScript
class. After compiling to JavaScript, the result will still be an instance of this class. One big advantage of this
approach is, that you can also use methods of this class.

@@ -22,3 +23,3 @@ With **json2typescript**, only a simple function call is necessary, as demonstrated in this TypeScript snippet:

let jsonStr: string = ...;
let jsonObj: object = JSON.parse(jsonStr);
let jsonObj: any = JSON.parse(jsonStr);

@@ -31,4 +32,3 @@ // Now you can map the json object to the TypeScript object automatically

> Tip: All `serialize()` and `deserialize()` methods may throw an `Error` in case of failure.
Make sure you catch errors in production!
> Tip: All `serialize()` and `deserialize()` methods may throw an `Error` in case of failure. Make sure you catch errors in production!

@@ -41,6 +41,9 @@ ---

> Tip: We earlier suggested to use the `@JsonObject(classId)` decorator, but did not enforce it.
Since v1.4.0, this is mandatory in order to make (de)serialization work properly with class inheritance.
In versions above v1.2.0 and below v1.4.0, it is possible to run into issues when not using the decorator.
> Warning: If you are reading this document on GitHub, it might be ahead of the published NPM version.
> Please refer to the [ReadMe on NPM](https://www.npmjs.com/package/json2typescript) if in doubt.
> Warning: We earlier suggested to use the `@JsonObject(classId)` decorator, but did not enforce it.
> Since v1.4.0, this is mandatory in order to make (de)serialization work properly with class inheritance.
> In versions above v1.2.0 and below v1.4.0, it is possible to run into issues when not using the decorator.
---

@@ -52,9 +55,9 @@

We developed **json2typescript** for Angular 2+ and Ionic 2+. In this document, we only cover this use case.
However, you may use our package for pure TypeScript or even JavaScript applications.
We developed **json2typescript** for Angular 2+ and Ionic 2+. In this document, we only cover this use case. However,
you may use our package for pure TypeScript or even JavaScript applications.
## Setup a Test Application
We recommend to use the official **angular cli** tool in order to set up a new Angular project.
Then, all you need to do is type the following into your operating system's terminal:
We recommend to use the official **angular cli** tool in order to set up a new Angular project. Then, all you need to do
is type the following into your operating system's terminal:

@@ -68,4 +71,4 @@ ```sh

Our package makes use of TypeScript decorators.
If not done already, please activate them in your **tsconfig.json** under `compilerOptions` as follows:
Our package makes use of TypeScript decorators. If not done already, please activate them in your **tsconfig.json**
under `compilerOptions` as follows:

@@ -75,11 +78,12 @@ ```json

"compilerOptions": {
[...]
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
[...]
[
...
]
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
[...]
}
```
> Tip: We have tried to make the compiler options of `json2typescript` to be as strict as possible.
This enables you to use compiler options such as `"strictNullChecks": true` or `"noImplicitAny": true` in your own project.
> Tip: We have tried to make the compiler options of `json2typescript` to be as strict as possible. This enables you to use compiler options such as `"strictNullChecks": true` or `"noImplicitAny": true` in your own project.

@@ -90,7 +94,7 @@ Now you are ready to use the package.

In order to use the **json2typescript** package, all you need to do is write decorators and import the package.
The following things need to be done if you would like to map JSON to existing classes:
In order to use the **json2typescript** package, all you need to do is write decorators and import the package. The
following things need to be done if you would like to map JSON to existing classes:
* Classes need to be preceeded by `@JsonObject(classIdentifier)`
* Properties need to be preceeded by `@JsonProperty(jsonProperty, conversionOption, isOptional)`
* Properties need to be preceeded by `@JsonProperty(jsonProperty, conversionOption, convertingMode)`
* Properties need to have a default value (or undefined), otherwise the mapper will not work

@@ -100,6 +104,7 @@

Assuming that you have created the **testApplication** in the step before and installed **json2typescript** as suggested, create a class in a new file **city.ts** with the following content:
Assuming that you have created the **testApplication** in the step before and installed **json2typescript** as
suggested, create a class in a new file **city.ts** with the following content:
```typescript
import {JsonObject, JsonProperty} from "json2typescript";
import { JsonObject, JsonProperty } from "json2typescript";

@@ -116,4 +121,4 @@ @JsonObject("City")

@JsonProperty("name", String)
name: string = undefined;
name: string = "";
// This maps the JSON key "founded" to the private class property "_founded".

@@ -123,11 +128,12 @@ // Note the use of public getter and setter.

@JsonProperty("founded", Number)
private _founded: number = undefined;
private _founded: number = 0;
get founded() { return this._founded; }
set founded(value: number) { this._founded = value; }
// This maps the JSON key "beautiful" to the class property "beautiful".
// If the JSON value is not of type boolean (or missing), there will be an exception.
@JsonProperty("beautiful", Boolean)
beautiful: boolean = undefined;
beautiful: boolean = false;
// This maps the JSON key "data" to the class property "data".

@@ -138,3 +144,3 @@ // We are not sure about the type, so we omit the second parameter.

data: any = undefined;
// This maps the JSON key "keywords" to the class property "keywords".

@@ -144,4 +150,4 @@ // This is an example of a string array. Note our syntax "[String]".

@JsonProperty("keywords", [String])
keywords: string[] = undefined; // or Array<string>
keywords: string[] = []; // or Array<string>
printInfo() {

@@ -153,3 +159,3 @@ if (this.beautiful)

}
}

@@ -161,4 +167,4 @@ ```

```typescript
import {City} from "./city";
import {JsonObject, JsonProperty} from "json2typescript";
import { City } from "./city";
import { JsonObject, JsonProperty } from "json2typescript";

@@ -171,4 +177,4 @@ @JsonObject("Country")

@JsonProperty("countryName", String)
name: string = undefined;
name: string = "";
// This maps the value of the JSON key "cities" to the class property "cities".

@@ -178,4 +184,4 @@ // If the JSON value is not of type array object (or missing), there will be an exception.

@JsonProperty("cities", [City])
cities: City[] = undefined;
cities: City[] = [];
}

@@ -187,5 +193,5 @@ ```

```typescript
import {Component, OnInit} from '@angular/core';
import {JsonConvert, OperationMode, ValueCheckingMode} from "json2typescript"
import {Country} from "./country";
import { Component, OnInit } from '@angular/core';
import { JsonConvert, OperationMode, ValueCheckingMode } from "json2typescript"
import { Country } from "./country";

@@ -200,24 +206,24 @@ @Component({

// Define a JSON object (could come from a HTTP service, parsed with JSON.parse() if necessary)
const jsonObject: object = {
const jsonObject: any = {
"countryName": "Switzerland",
"cities": [
{
"id": 1,
"name": "Basel",
"founded": -200,
"beautiful": true,
{
"id": 1,
"name": "Basel",
"founded": -200,
"beautiful": true,
"data": 123,
"keywords": ["Rhine", "River"]
"keywords": ["Rhine", "River"]
},
{
"id": 1,
"name": "Zurich",
"founded": 0,
"beautiful": false,
{
"id": 1,
"name": "Zurich",
"founded": 0,
"beautiful": false,
"data": "no",
"keywords": ["Limmat", "Lake"]
"keywords": ["Limmat", "Lake"]
}
]
};
// Choose your settings

@@ -229,3 +235,3 @@ // Check the detailed reference in the chapter "JsonConvert class properties and methods"

jsonConvert.valueCheckingMode = ValueCheckingMode.DISALLOW_NULL; // never allow null
// Map to the country class

@@ -239,4 +245,5 @@ let country: Country;

}
}
}
```
Play around with the JSON to provocate exceptions when deserializing the object.

@@ -246,4 +253,4 @@

Avoid circular depencencies on the classes that use `json2typescript`.
Even if you don't have any errors in your IDE, `json2typescript` will not properly work in this case.
Avoid circular dependencies on the classes that use `json2typescript`. Even if you don't have any errors in your
IDE, `json2typescript` will not properly work in this case.

@@ -256,4 +263,4 @@ ---

Decorators should be used whenever you would like to map JSON with TypeScript data.
As of now, you must not use more than one decorator per class or property.
Decorators should be used whenever you would like to map JSON with TypeScript data. As of now, you must not use more
than one decorator per class or property.

@@ -269,4 +276,3 @@ ### Class decorators

> Warning: The class decorator uses the parameter to identify the class.
Please use a unique identifier for each class in your project, for example simply the name of the class.
> Warning: The class decorator uses the parameter to identify the class. Please use a unique identifier for each class in your project, for example simply the name of the class.

@@ -279,16 +285,33 @@ > Tip: Make sure you import `JsonObject` from `json2typescript`.

> Note: This class identifier may be used for automatic instantiation when enabling the discriminator feature.
### Property decorators
Property decorators are a vital part for type checking. It is important that the type in the decorator matches the TypeScript type.
Property decorators are a vital part for type checking. It is important that the type in the decorator matches the
TypeScript type.
For class properties to be visible to the mapper they **must be initialized**, otherwise they are ignored.
They can be initialized using any (valid) value or `undefined`.
See the example below for better understanding:
```typescript
@JsonObject("User")
export class User {
@JsonProperty("jsonPropertyName", String, false)
name: string = undefined;
// A correct example
@JsonProperty("name", String, false)
name: string = "";
// An incorrect example
@JsonProperty("alias", string, false) // Wrong type: Must use String instead.
alias: string = "";
// An incorrect example
@JsonProperty("expertise", String, false)
expertise: string; // No initialization: Property will be ignored without visible exception
}
```
Important note: You must assign any (valid) value or `undefined` to your property at
initialization, otherwise our mapper does **not** work and will simply ignore the property.
> **Important note**: You must assign any (valid) value or `undefined` to your property at initialization, otherwise our mapper does **not** work and will simply ignore the property. Assigning no value is not the same as assigning `undefined` in context of `json2typescript`. Non-initialized properties will not trigger any exception, as **they are invisible to the mapper**.

@@ -299,17 +322,16 @@ > Tip: Make sure you import `JsonObject` and `JsonProperty` from `json2typescript`.

The first parameter of `@JsonProperty` is the JSON object property name.
It happens that the property names given by the server are very ugly.
Here you can map any json property name to the `User` property `name`.
In our case, `json["jsonPropertyName"]` gets mapped to `user.name`.
The first parameter of `@JsonProperty` is the JSON object property name. It happens that the property names given by the
server are very ugly. Here you can map any json property name to the `User` property `name`. In our
case, `json["jsonPropertyName"]` gets mapped to `user.name`.
#### Second parameter (optional): conversionOption
The second parameter of `@JsonProperty` describes what happens when doing the mapping between JSON and TypeScript objects.
This parameter is optional; the default value is `Any` (which means no type check is done when the mapping happens).
The second parameter of `@JsonProperty` describes what happens when doing the mapping between JSON and TypeScript
objects. This parameter is optional; the default value is `Any` (which means no type check is done when the mapping
happens).
##### Use of expected type
If you would like that `json2typescript` performs an automatic type
check according to given TypeScript types, you can pass a type you
expect. Follow the following guide when doing that:
If you would like that `json2typescript` performs an automatic type check according to given TypeScript types, you can
pass a type you expect. Follow the following guide when doing that:

@@ -323,3 +345,3 @@ - Make sure you pass the class name and not an instance of the class.

| Expected type | TypeScript type |
| --- | :--- |
| --- | --- |
| String | string |

@@ -337,5 +359,4 @@ | Number | number |

At first, our array notation on the left looks odd.
But this notation allows you to define even nested arrays.
See the examples at the end of this document for more info about nesting arrays.
At first, our array notation on the left looks odd. But this notation allows you to define even nested arrays. See the
examples at the end of this document for more info about nesting arrays.

@@ -345,7 +366,6 @@ ##### Adding a custom converter

More advanced users may need to use custom converters. If you want
`json2typescript` to use your custom converter, you need to follow these
steps:
`json2typescript` to use your custom converter, you need to follow these steps:
- Write a converter class that implements `JsonCustomConvert<T>` where
`<T>` is the type resulting in the TypeScript class.
`<T>` is the type resulting in the TypeScript class.
- Make sure you add the `@JsonConverter` decorator to this class (see next chapter how).

@@ -362,40 +382,79 @@ - Pass your converter class as second param in the `@JsonProperty` decorator

@JsonProperty("birthdate", DateConverter)
birthdate: Date = undefined;
birthdate: Date = new Date();
}
```
#### Third parameter (optional): isOptional
#### Third parameter (optional): convertingMode
The third parameter of `@JsonProperty` determines whether the `jsonProperty` has to be present in the json.
This parameter is optional; the default value is false.
The third parameter of `@JsonProperty` determines how nullable property types should be serialized and deserialized.
Nullable types are either missing (in JSON), undefined (in TypeScript) or null (both). This parameter is optional; the
default value is `PropertyConvertingMode.MAP_NULLABLE`.
By default, `JsonConvert` throws an exception if a decorated class property cannot be found in the given JSON when deserializing.
If you set the third parameter to true, there is no exception when it is missing.
The type is still checked as soon the property is present again.
See also the property `propertyConvertingMode` of the `JsonConvert` instance.
The same applies for the case when you try to serialize a TypeScript object to a JSON object. If the property is not defined in the class and optional, it will not be added to the JSON object.
The values should be used as follows:
> Tip: Some API's return null instead of omitting optional values.
If you flag a property as optional, `json2typescript` will ignore (JSON) null values at deserialization and keep the default value of the property instead.
This fact is particularly helpful if your project uses TypeScript `strictNullChecks` or/and disallows `null` values through the `valueCheckingMode` property in `json2typescript`.
Furthermore, note that the instance property `ignoreRequiredCheck` – if set to true – overrides all `isOptional` values for all properties.
- `PropertyConvertingMode.MAP_NULLABLE`: the mapper is applied, type is checked
- `PropertyConvertingMode.IGNORE_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the
property is not added to the result
- `PropertyConvertingMode.PASS_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the
property is added with its value to the result
> Tip: Make sure you import the `ENUM` `PropertyConvertingMode` when assigning a value to this property.
##### Handling null, undefined and absent values
Be careful when handling special values as `null`, `undefined` and `absent` properties.
By default, `json2typescript` throws an exception if a decorated class property cannot be found in the given JSON when
deserializing. If you set the third parameter to `IGNORE_NULLABLE` or `PASS_NULLABLE`, there will be no exception when
it is missing. The type of a property will only be checked if the property is present in the JSON and not `undefined`
or `null`.
The global setting of `valueCheckingMode` determines whether you want to allow `null` values for objects or properties.
We recommend to use the most strict option and also set your `TypeScript` compiler to the strict mode.
The following table explains the difference between the three property converting modes:
| **ALLOW_NULL** | `serialize(null)` | `serialize(undefined)` | `deserialize(null)` | `deserialize(undefined)` |
| --- | --- | --- | --- | --- |
| `MAP_NULLABLE` | `null` | error | `null` | error |
| `IGNORE_NULLABLE` | `undefined` (missing) | `undefined` (missing) | default value | default value |
| `PASS_NULLABLE` | `null` | `undefined` (missing) | `null` | `undefined` |
| |
| **DISALLOW_NULL** | `serialize(null)` | `serialize(undefined)` | `deserialize(null)` | `deserialize(undefined)` |
| `MAP_NULLABLE` | error | error | error | error |
| `IGNORE_NULLABLE` | `undefined` (missing) | `undefined` (missing) | default value | default value |
| `PASS_NULLABLE` | `null` | `undefined` (missing) | `null` | `undefined` |
As shown in this table, a property with the default setting `MAP_NULLABLE` is never allowed to be `undefined` (or
missing). The `valueCheckingMode` determines, whether `null` is allowed.
> Tip: If you want `undefined` to be treated in the same way as `null` values, you may set the instance `mapUndefinedToNull` property to `true`.
#### Important notes
* Make sure you define the expected type as accurate as possible, even if you expect primitive types.
* By default, casting primitives into other primitives is not allowed. Check the public properties below in this document to change this behaviour.
* By default, casting primitives into other primitives is not allowed. Check the public properties below in this
document to change this behaviour.
* By default, primitives are not allowed to be null. Check the public properties below in this document to change this.
* If you don't know the type, you may use `Any` as expected type. You may also omit the second parameter of `@JsonProperty`.
* If you don't know the type, you may use `Any` as expected type. You may also omit the second parameter
of `@JsonProperty`.
#### More about the array syntax
* You can allow arrays by using the bracket notation combined with the types as seen above. For example: `[String]` for a string array
* Mixing arrays is allowed. For example: `[String, Number]` for an array where the first entry is a string, the second is a number.
* If the real array is longer than indicated here, the last type will be forced to the rest of the array entries (above: `Number`).
* You can allow arrays by using the bracket notation combined with the types as seen above. For example: `[String]` for
a string array
* Mixing arrays is allowed. For example: `[String, Number]` for an array where the first entry is a string, the second
is a number.
* If the real array is longer than indicated here, the last type will be forced to the rest of the array entries (
above: `Number`).
* This means, `[String, Number]` is equivalent to `[String, Number, Number]` and so on.
* Nesting arrays and objects are allowed. For example: `[[String, Number], User]`.
* This is equivalent to `[[String, Number, Number], User, User]` and so on.
* As further example, `[[String]]` is equal to `[[String],[String]]` which is equal to `[[String,String], [String,String]]` and so on.
* As further example, `[[String]]` is equal to `[[String],[String]]` which is equal
to `[[String,String], [String,String]]` and so on.
* If an array has less elements as given in the expected type, no exception is thrown.
* For example, if we define `[String]` or the equivalent `[String, String]` no exception is thrown - even if the JSON gives us an empty array.
* For example, if we define `[String]` or the equivalent `[String, String]` no exception is thrown - even if the JSON
gives us an empty array.

@@ -406,5 +465,5 @@ > Tip: See the examples at the end of this document for advanced examples for nesting arrays.

In some cases, you may need to make custom conversion between JSON objects and TypeScript objects. You can define custom converters like this:
In some cases, you may need to make custom conversion between JSON objects and TypeScript objects. You can define custom
converters like this:
```typescript

@@ -414,4 +473,5 @@ @JsonConverter

serialize(date: Date): any {
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
}
deserialize(date: any): Date {

@@ -425,5 +485,6 @@ return new Date(date);

Assume that in your JSON you have a date in a standardized format, such as `2017-07-19 10:00:00`. You could use the custom converter class above to make sure it is stored as a real TypeScript `Date` in your class. For your property, you simply have use the `@JsonProperty` decorator as follows:
Assume that in your JSON you have a date in a standardized format, such as `2017-07-19 10:00:00`. You could use the
custom converter class above to make sure it is stored as a real TypeScript `Date` in your class. For your property, you
simply have use the `@JsonProperty` decorator as follows:
```typescript

@@ -433,3 +494,3 @@ @JsonObject("User")

@JsonProperty("date", DateConverter)
date: Date = undefined;
date: Date = new Date();
}

@@ -440,4 +501,2 @@ ```

## JsonConvert class properties and methods

@@ -451,5 +510,6 @@

Determines how the JsonConvert class instance should operate.
Determines how the JsonConvert class instance should operate.
You may assign three different values:
- `OperationMode.DISABLE`: json2typescript will be disabled, no type checking or mapping is done

@@ -461,9 +521,9 @@ - `OperationMode.ENABLE`: json2typescript is enabled, but only errors are logged

In some cases, you might consider disabling `json2typescript` in production by setting the `OperationMode.DISABLE` flag.
This only works in case you only use plain objects without functionality and no mapping.
However, disabling `json2typescript` might give you a performance advantage in heavy projects.
In some cases, you might consider disabling `json2typescript` in production by setting the `OperationMode.DISABLE` flag.
This only works in case you only use plain objects without functionality and no mapping. However,
disabling `json2typescript` might give you a performance advantage in heavy projects.
In case you have issues to find bugs, you can enable additional logging by setting the `OperationMode.LOGGING` flag.
Please note that every serializing and deserializing is heavily logged to the console and will make your application slower.
Never use this flag in production.
Please note that every serializing and deserializing is heavily logged to the console and will make your application
slower. Never use this flag in production.

@@ -476,4 +536,4 @@ > Tip: Make sure you import the `ENUM` `OperationMode` when assigning a value to this property.

Determines which types are allowed to be null.
You may assign three different values:
Determines which types are allowed to be null in the deserialization. You may assign three different values:
* `ValueCheckingMode.ALLOW_NULL`: All given values can be null

@@ -483,10 +543,19 @@ * `ValueCheckingMode.ALLOW_OBJECT_NULL`: Objects can be null, but primitive types cannot be null

The default is `ValueCheckingMode.ALLOW_OBJECT_NULL`.
The default is `ValueCheckingMode.ALLOW_OBJECT_NULL`.
> Tip: Make sure you import the `ENUM` `ValueCheckingMode` when assigning a value to this property.
> Tip: The TypeScript documentation suggests to avoid null values.
Compile your TypeScript code with `strictNullChecks=true` and set the `valueCheckingMode` to disallow null values.
If your API returns `null` in some cases, simply mark these properties as optional in the corresponding `JsonProperty` decorator to avoid errors on runtime.
> Tip: The TypeScript documentation suggests to avoid null values. Compile your TypeScript code with `strictNullChecks=true` and set the `valueCheckingMode` to disallow null values. If your API returns `null` in some cases, simply mark these properties as optional in the corresponding `JsonProperty` decorator to avoid errors on runtime.
#### Map undefined to null
`(number) JsonConvert.mapUndefinedToNull`
Determines whether a missing or undefined property value should be considered as null or not.
If true, a missing JSON value will be added and set as null before deserialization. For serialization, undefined values
will be set to null before serialization.
> Note: ValueCheckingMode and PropertyConvertingMode determine whether an error will be thrown during serialization or deserialization.
#### Ignore primitive checks

@@ -496,4 +565,4 @@

Determines whether primitive types should be checked.
If true, it will be allowed to assign primitive to other primitive types.
Determines whether primitive types should be checked. If true, it will be allowed to assign primitive to other primitive
types.

@@ -506,19 +575,57 @@ The default is `false`.

Determines the rule of how JSON properties shall be matched with class properties during deserialization.
You may assign the following two values:
Determines the rule of how JSON properties shall be matched with class properties during deserialization. You may assign
the following two values:
* `PropertyMatchingRule.CASE_STRICT`: JSON properties need to match exactly the names in the decorators
* `PropertyMatchingRule.CASE_INSENSITIVE`: JSON properties need to match names in the decorators, but names they are not case sensitive
* `PropertyMatchingRule.CASE_INSENSITIVE`: JSON properties need to match names in the decorators, but names they are not
case sensitive
The default is `PropertyMatchingRule.CASE_STRICT`.
#### Ignore required property checks
#### Property converting mode
`(bool) JsonConvert.ignoreRequiredCheck`
`(number|undefined) JsonConvert.propertyConvertingMode`
Determines whether the check for required properties should be ignored, making all mapped values optional, whether or not the isOptional property mapping parameter is set.
If true, any missing properties (undefined) when serializing or deserializing will be ignored, as if they were marked optional.
Note that properties explicitly set to null will be unaffected by this flag – they will be ignored if optional and included if not.
Determines how nullable property types should be serialized and deserialized. Nullable types are either missing (in
JSON), undefined (in TypeScript) or null (both).
If the propertyConvertingMode has a non-undefined value, it overrides the individual settings of every property. See
also the third parameter of the `@JsonProperty` decorator.
The values should be used as follows:
- `PropertyConvertingMode.MAP_NULLABLE`: the mapper is applied, type is checked
- `PropertyConvertingMode.IGNORE_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the
property is
* not added to the result
- `PropertyConvertingMode.PASS_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the
property is
* added with its value to the result
The default is `PropertyMatchingRule.MAP_NULLABLE`.
> Note: This property is usually only temporarily set and should be used with caution.
> It replaces the deprecated property `ignoreRequiredCheck`.
#### Use discriminator
`(bool) JsonConvert.useDiscriminator`
Determines if discriminators should be used.
If this option is set to true, all registered classes will be serialized with an additional discriminator property (default: "$type"), which has the key of the class (given in the @JsonObject decorator) as value.
When deserializing an object containing the discriminator property, json2typescript will attempt to automatically instantiate the correct type (by comparing the value of the discriminator property with the registered classes).
The default is `false`.
> Note: At the end of this document you may find an example on how to use the discriminator feature.
#### Discriminator property name
`(string) JsonConvert.discriminatorPropertyName`
Defines the name of the discriminator property.
The default is `"$type"`.
### Public methods

@@ -529,38 +636,78 @@

#### Serializing (TypeScript to JSON)
`(any) serialize(data: any | any[])`
`(any|any[]) serialize<T extends object, U extends object = {}>(data: T | T[], classReference?: { new(): U })`
Tries to serialize a TypeScript object or array of objects to JSON.
The first parameter must be a TypeScript object or array, the second parameter is the optional class reference.
If you provide only one parameter, the class for serialization is inferred automatically. For example, if you
call `jsonConvert.serialize(user)` where `user` is an instance of the class `User`, `json2typescript` will automatically
use this class for serialization.
By providing two parameters, it will override the class for serialization. For example, this allows you to
call `jsonConvert.serialize(userObject, User)` where `userObject` is just a plain TypeScript `any` object.
The returned value will be `any` object or an array of `any` objects.
> Tip: The return value is not a string. In case you need a string as result, use `JSON.stringify()` after calling the serialize method.
You may optionally provide a class constructor to use the `@JsonProperty` mappings defined for that class to serialize
the data object(s), instead of mappings defined on the data class. Note that if the data is an array, the mappings from
the constructor class are used for *all* elements in the array. If no constructor is provided, the mappings from the
data object class are used to serialize the data object(s).
> Tip: This feature is helpful if you need to serialize an object that was not created using a class constructor, or if you want to serialize a subclass with only the properties of the superclass.
#### Deserializing (JSON to TypeScript)
`(T | T[]) deserialize(json: any, classReference: { new(): T | T[] })`
`(T | T[]) deserialize<T extends object>(json: any, classReference: { new(): T })`
Tries to deserialize given JSON to a TypeScript object or array of objects.
> Tip: The param `json` must not be a string, but an `object` or an `array`. Use `JSON.parse()` before applying the deserialize method in case you have a json string.
The first parameter must be a Typescript object or array, the second parameter is the class reference.
The returned value will be an instance or an array of instances of the given class reference.
> Tip: The param `json` must not be a string, but an `object` or an `array`. Use `JSON.parse()` before applying the deserialize method in case you have a json string.
#### Registering and unregistering classes
`void registerClasses(...classReferences: { new(): any }[])`
Registers a list of classes to be used in the discriminator feature.
`void ungisterClasses(...classReferences: { new(): any }[])`
Unregisters a list of classes from the discriminator feature.
`void unregisterAllClasses()`
Unregisters all classes from the discriminator feature.
> Note: You only need to register and unregister classes if you use the discriminator feature. Otherwise, these methods are without any effect.
#### Other methods
The methods `serialize()` and `deserialize()` will automatically detect the dimension of your param (either object or array).
In case you would like to force `json2typescript` to use a specific way, you can use the following methods instead:
- `(any) serializeObject(instance: any)`
- `(any[]) serializeArray(instanceArray: any[])`
- `(T) deserializeObject(jsonObject: any, classReference: { new(): T })`
- `(T[]) deserializeArray(jsonArray: any[], classReference: { new(): T })`
The methods `serialize()` and `deserialize()` will automatically detect the dimension of your param (either object or
array). In case you would like to force `json2typescript` to use a specific way, you can use the following methods
instead:
- `(any) serializeObject<T extends object, U extends object = {}>(data: T, classReference?: { new(): U })`
- `(any[]) serializeArray<T extends object, U extends object = {}>(dataArray: T[], classReference?: { new(): U })`
- `(T) deserializeObject<T extends object>(jsonObject: any, classReference: { new(): T })`
- `(T[]) deserializeArray<T extends object>(jsonArray: any[], classReference: { new(): T })`
---
# Further examples
# Advanced strategies
In case you don't have enough complex examples yet, you may find some more in this section.
In this section you will find additional examples.
## Nesting arrays
It is heavily discouraged to use nested arrays and use different types in a JSON api.
If you need them anyway, here is how you have to define the types:
It is heavily discouraged to use nested arrays and use different types in a JSON API. If you need them anyway, here is
how you have to define the types:

@@ -573,6 +720,12 @@ ### 1) Nested arrays with same type

{
"jsonKeyOfWeirdKeywords": [
["Hello", "World"],
["Bye", "Earth"]
"jsonKeyOfWeirdKeywords": [
[
"Hello",
"World"
],
[
"Bye",
"Earth"
]
]
}

@@ -587,3 +740,3 @@ ```

@JsonProperty("jsonKeyOfWeirdKeywords", [[String, String], [String, String]])
keywords: any = undefined;
keywords: (string[])[] = [];
}

@@ -600,6 +753,9 @@ ```

{
"jsonKeyOfWeirdKeywords": [
["FC", "Basel"],
1893
]
"jsonKeyOfWeirdKeywords": [
[
"FC",
"Basel"
],
1893
]
}

@@ -614,3 +770,3 @@ ```

@JsonProperty("jsonKeyOfWeirdKeywords", [[String, String], Number])
keywords: any = undefined;
keywords: (string[] | number)[] = [];
}

@@ -621,11 +777,75 @@ ```

## Automatic instantiation using the discriminator feature
If your server adds a discriminator property to every JSON object, `json2typescript` is able to automatically instantiate objects.
First, set up the discriminator feature for a class, for example
```typescript
@JsonObject("app.example.User")
export class User {
@JsonProperty("name", String)
name: string = "";
}
```
Now, set up a `JsonConvert` to enable the discriminator feature and activate it for the classes you like:
```typescript
// Set up json convert
let jsonConvert: JsonConvert = new JsonConvert();
jsonConvert.useDiscriminator = true; // enable the discriminator
jsonConvert.discriminatorPropertyName = "$type"; // this is the property name
jsonConvert.registerClasses(User); // register all classes
// Assume the following JSON object coming from your server
const jsonObject: any = {
"name": "Walter",
"$type": "app.example.User" // the value of $type matches the @JsonObject decorator above
}
// This is how you would traditionally map an object
// But we have enabled the discriminator functionality and registered the User class
// In that case, the second parameter (User) here is ignored
const user1: User = jsonConvert.deserialize(jsonObject, User);
// But now you may automatically map it thanks to the $type property
const user2: User = jsonConvert.deserialize<User>(jsonObject);
```
> Note: This feature is particularly useful when doing dynamic mapping.
> Otherwise, you just may provide the type yourself (as done above with `user1`) and disable the discriminator feature.
A real-world example for the discriminator feature is the mapping of child classes.
Assume that you might have two classes `AdminUser` and `NormalUser` that inherit from `User`.
The web client sometimes cannot know the type in advance.
If you use the discriminator feature, the server can define the type in the JSON and `json2typescript` will properly instantiate the desired class.
This means, your property can be safely declared in TypeScript as union type of `AdminUser | NormalUser` instead of `User`.
> Warning: If you enable the discriminator feature and try to deserialize a JSON object to a registered class instance, the second parameter of the `deserialize` methods is always ignored.
---
# Tools
## Class decorator generator
Since version 1.4, `json2typescript` requires the `@JsonObject("ClassName")` decorator in front of the TypeScript class
definition. GitHub user `tlmurphy` created a Python script that automatically generates the decorator with the original
class name as parameter.
More: https://gist.github.com/tlmurphy/71b58c71e594899120da365159d7d40d
---
# Contributors
This NPM package was originally created in 2016 by **Andreas Aeschlimann**, software architect at his own company (**AppVision GmbH**) and scientific researcher at the **Digital Humanities Lab** (**University of Basel**).
This NPM package was originally created in 2016 by **Andreas Aeschlimann**, founder of and software architect at **AppVision GmbH**.
## Special thanks
You are welcome to report issues and discuss enhancements to make this package even more useful.
Thanks for the input and all the pull requests from the community!
You are welcome to report issues and discuss enhancements to make this package even more useful. Thanks for the input
and all the pull requests from the community!
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc