{"id":13452474,"url":"https://github.com/AppVision-GmbH/json2typescript","last_synced_at":"2025-03-23T19:34:25.914Z","repository":{"id":39789356,"uuid":"73762601","full_name":"appvision-gmbh/json2typescript","owner":"appvision-gmbh","description":"Map JSON to a TypeScript class with secure type checking!","archived":false,"fork":false,"pushed_at":"2023-01-27T12:14:03.000Z","size":1805,"stargazers_count":278,"open_issues_count":30,"forks_count":55,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-12T02:31:11.396Z","etag":null,"topics":["angular","custom-converter","ionic","ionic-framework","json-api","json-converter","json-objects","json-typescript","map-json","npm-package","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/json2typescript","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/appvision-gmbh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-15T01:15:24.000Z","updated_at":"2024-09-19T02:59:53.000Z","dependencies_parsed_at":"2023-02-05T05:01:48.934Z","dependency_job_id":null,"html_url":"https://github.com/appvision-gmbh/json2typescript","commit_stats":null,"previous_names":["dhlab-basel/json2typescript"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appvision-gmbh%2Fjson2typescript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appvision-gmbh%2Fjson2typescript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appvision-gmbh%2Fjson2typescript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appvision-gmbh%2Fjson2typescript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/appvision-gmbh","download_url":"https://codeload.github.com/appvision-gmbh/json2typescript/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221900965,"owners_count":16898997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","custom-converter","ionic","ionic-framework","json-api","json-converter","json-objects","json-typescript","map-json","npm-package","typescript"],"created_at":"2024-07-31T07:01:25.124Z","updated_at":"2024-10-28T18:31:23.956Z","avatar_url":"https://github.com/appvision-gmbh.png","language":"TypeScript","readme":"[![npm](https://img.shields.io/npm/v/json2typescript.svg)](https://www.npmjs.com/package/json2typescript)\n![](https://img.shields.io/npm/dt/json2typescript.svg?style=flat)\n![](https://img.shields.io/bundlephobia/minzip/json2typescript.svg?style=flat)\n![](https://img.shields.io/npm/l/json2typescript.svg?style=flat)\n\n# json2typescript\n\nIn Angular applications, everyone consumes JSON API's from an external source. Type checking and object mapping is only\npossible in TypeScript, but not in the JavaScript runtime. As the API may change at any point, it is important for\nlarger projects to verify the consumed data.\n\n**json2typescript** is a small package containing a helper class that maps JSON objects to an instance of a TypeScript\nclass. After compiling to JavaScript, the result will still be an instance of this class. One big advantage of this\napproach is, that you can also use methods of this class.\n\nWith **json2typescript**, only a simple function call is necessary, as demonstrated in this TypeScript snippet:\n\n```typescript\n// Assume that you have a class named User defined at some point\n// Assume that you get a JSON string from a webservice\nlet jsonStr: string = ...;\nlet jsonObj: any = JSON.parse(jsonStr);\n\n// Now you can map the json object to the TypeScript object automatically\nlet jsonConvert: JsonConvert = new JsonConvert();\nlet user: User = jsonConvert.deserializeObject(jsonObj, User);\nconsole.log(user); // prints User{ ... } in JavaScript runtime, not Object{ ... }\n```\n\n\u003e Tip: All `serialize()` and `deserialize()` methods may throw an `Error` in case of failure. Make sure you catch errors in production!\n\n---\n\n# Changelog\n\nSee the changelog in the separate file for bug fixes, new features and breaking changes: [Changelog](CHANGELOG.md)\n\n\u003e Warning: If you are reading this document on GitHub, it might be ahead of the published NPM version.\n\u003e Please refer to the [ReadMe on NPM](https://www.npmjs.com/package/json2typescript) if in doubt.\n\n\u003e Warning: We earlier suggested to use the `@JsonObject(classIdentifier)` decorator, but did not enforce it. \n\u003e Since v1.4.0, it is mandatory to use a unique classIdentifier for every class in order to make (de)serialization work properly with class inheritance. \n\u003e In versions above v1.2.0 and below v1.4.0, it is possible to run into issues when not using the decorator.\n\n---\n\n# Getting started\n\n## Requirements\n\nWe developed **json2typescript** for Angular 2+ and Ionic 2+. In this document, we only cover this use case. However,\nyou may use our package for pure TypeScript or even JavaScript applications.\n\n## Setup a Test Application\n\nWe recommend to use the official **angular cli** tool in order to set up a new Angular project. Then, all you need to do\nis type the following into your operating system's terminal:\n\n```sh\nng new testApplication\ncd testApplication\n\nnpm install json2typescript\n```\n\nOur package makes use of TypeScript decorators. If not done already, please activate them in your **tsconfig.json**\nunder `compilerOptions` as follows:\n\n```json\n{\n  \"compilerOptions\": {\n[\n  ...\n]\n\"experimentalDecorators\": true,\n\"emitDecoratorMetadata\": true,\n[...]\n}\n```\n\n\u003e 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.\n\nNow you are ready to use the package.\n\n## Mapping example\n\nIn order to use the **json2typescript** package, all you need to do is write decorators and import the package. The\nfollowing things need to be done if you would like to map JSON to existing classes:\n\n* Classes need to be preceded by `@JsonObject(classIdentifier)` where the classIdentifier is unique in the whole project\n* Properties need to be preceded by `@JsonProperty(jsonProperty, conversionOption, convertingMode)`\n* Properties need to have a default value (or undefined), otherwise the mapper will not work\n\nSee below an example, so you can learn from it how **json2typescript** works best.\n\nAssuming that you have created the **testApplication** in the step before and installed **json2typescript** as\nsuggested, create a class in a new file **city.ts** with the following content:\n\n```typescript\nimport { JsonObject, JsonProperty } from \"json2typescript\";\n\n@JsonObject(\"City\") // Make sure \"City\" is a unique identifier for this class\nexport class City {\n\n    // This property has no @JsonProperty. \n    // It will not be mapped.\n    id: number = 123;\n\n    // This maps the value of the JSON key \"name\" to the class property \"name\".\n    // If the JSON value is not of type string (or missing), there will be an exception.\n    @JsonProperty(\"name\", String)\n    name: string = \"\";\n\n    // This maps the JSON key \"founded\" to the private class property \"_founded\".\n    // Note the use of public getter and setter.\n    // If the JSON value is not of type number (or missing), there will be an exception.\n    @JsonProperty(\"founded\", Number)\n    private _founded: number = 0;\n    get founded() { return this._founded; }\n\n    set founded(value: number) { this._founded = value; }\n\n    // This maps the JSON key \"beautiful\" to the class property \"beautiful\".\n    // If the JSON value is not of type boolean (or missing), there will be an exception.\n    @JsonProperty(\"beautiful\", Boolean)\n    beautiful: boolean = false;\n\n    // This maps the JSON key \"data\" to the class property \"data\".\n    // We are not sure about the type, so we omit the second parameter.\n    // There will be an exception if the JSON value is missing.\n    @JsonProperty(\"data\") // is the same as @JsonProperty(\"data\", Any)\n    data: any = undefined;\n\n    // This maps the JSON key \"keywords\" to the class property \"keywords\".\n    // This is an example of a string array. Note our syntax \"[String]\".\n    // In the further examples at the end of this document, you can see how to nest complex arrays.\n    @JsonProperty(\"keywords\", [String])\n    keywords: string[] = []; // or Array\u003cstring\u003e\n\n    printInfo() {\n        if (this.beautiful)\n            console.log(this.name + \" was founded in \" + this.founded + \" and is really beautiful!\");\n        else\n            console.log(this.name + \" was founded in \" + this.founded + \".\");\n    }\n\n}\n```\n\nNow create a file **country.ts** with the following content:\n\n```typescript\nimport { City } from \"./city\";\nimport { JsonObject, JsonProperty } from \"json2typescript\";\n\n@JsonObject(\"Country\") // Make sure \"Country\" is a unique identifier for this class\nexport class Country {\n\n    // This maps the value of the JSON key \"countryName\" to the class property \"name\".\n    // If the JSON value is not of type string (or missing), there will be an exception.\n    @JsonProperty(\"countryName\", String)\n    name: string = \"\";\n\n    // This maps the value of the JSON key \"cities\" to the class property \"cities\".\n    // If the JSON value is not of type array object (or missing), there will be an exception.\n    // There will be an exception too if the objects in the array do not match the class \"City\".\n    @JsonProperty(\"cities\", [City])\n    cities: City[] = [];\n\n}\n```\n\nThen navigate to the file **app.component.ts** and add the following code:\n\n```typescript\nimport { Component, OnInit } from '@angular/core';\nimport { JsonConvert, OperationMode, ValueCheckingMode } from \"json2typescript\"\nimport { Country } from \"./country\";\n\n@Component({\n    selector: 'app-root',\n    templateUrl: './app.component.html',\n    styleUrls: ['./app.component.css']\n})\nexport class AppComponent implements OnInit {\n    ngOnInit() {\n        // Define a JSON object (could come from a HTTP service, parsed with JSON.parse() if necessary)\n        const jsonObject: any = { \n            \"countryName\": \"Switzerland\", \n            \"cities\": [\n                {\n                    \"id\": 1,\n                    \"name\": \"Basel\",\n                    \"founded\": -200,\n                    \"beautiful\": true,\n                    \"data\": 123,\n                    \"keywords\": [\"Rhine\", \"River\"]\n                },\n                {\n                    \"id\": 1,\n                    \"name\": \"Zurich\",\n                    \"founded\": 0,\n                    \"beautiful\": false,\n                    \"data\": \"no\",\n                    \"keywords\": [\"Limmat\", \"Lake\"]\n                }\n            ]\n        };\n\n        // Choose your settings\n        // Check the detailed reference in the chapter \"JsonConvert class properties and methods\"\n        let jsonConvert: JsonConvert = new JsonConvert();\n        jsonConvert.operationMode = OperationMode.LOGGING; // print some debug data\n        jsonConvert.ignorePrimitiveChecks = false; // don't allow assigning number to string etc.\n        jsonConvert.valueCheckingMode = ValueCheckingMode.DISALLOW_NULL; // never allow null\n\n        // Map to the country class\n        let country: Country;\n        try {\n            country = jsonConvert.deserializeObject(jsonObject, Country);\n            country.cities[0].printInfo(); // prints: Basel was founded in -200 and is really beautiful!\n        } catch (e) {\n            console.log((\u003cError\u003ee));\n        }\n    }\n```\n\nPlay around with the JSON to provocate exceptions when deserializing the object.\n\n## Important notes\n\nAvoid circular dependencies on the classes that use `json2typescript`. Even if you don't have any errors in your\nIDE, `json2typescript` will not properly work in this case.\n\n---\n\n# Detailed reference\n\n## Class and property decorators\n\nDecorators should be used whenever you would like to map JSON with TypeScript data. As of now, you must not use more\nthan one decorator per class or property.\n\n### Class decorators\n\nThe class decorators are used infront of the class declaration and do support one parameter:\n\n```typescript\n@JsonObject(\"User\")\nexport class User {}\n```\n\n\u003e 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.\n\n\u003e Tip: Make sure you import `JsonObject` from `json2typescript`.\n\n#### First parameter: classIdentifier\n\nThe first parameter of `@JsonObject` must be a unique class identifier, usually just the class name.\n\n\u003e Note: This class identifier may be used for automatic instantiation when enabling the discriminator feature.\n\n### Property decorators\n\nProperty decorators are a vital part for type checking. It is important that the type in the decorator matches the\nTypeScript type.\n\nFor class properties to be visible to the mapper they **must be initialized**, otherwise they are ignored. \nThey can be initialized using any (valid) value or `undefined`.\nSee the example below for better understanding:\n\n```typescript\n@JsonObject(\"User\")\nexport class User {\n    \n    // A correct example\n    @JsonProperty(\"name\", String, false)\n    name: string = \"\";\n    \n    // An incorrect example\n    @JsonProperty(\"alias\", string, false) // Wrong type: Must use String instead.\n    alias: string = \"\";\n  \n    // An incorrect example\n    @JsonProperty(\"expertise\", String, false)\n    expertise: string; // No initialization: Property will be ignored without visible exception\n    \n}\n```\n\n\u003e **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**.\n\n\u003e Tip: Make sure you import `JsonObject` and `JsonProperty` from `json2typescript`.\n\n#### First parameter: jsonProperty\n\nThe first parameter of `@JsonProperty` is the JSON object property name. It happens that the property names given by the\nserver are very ugly. Here you can map any json property name to the `User` property `name`. In our\ncase, `json[\"jsonPropertyName\"]` gets mapped to `user.name`.\n\n#### Second parameter (optional): conversionOption\n\nThe second parameter of `@JsonProperty` describes what happens when doing the mapping between JSON and TypeScript\nobjects. This parameter is optional; the default value is `Any` (which means no type check is done when the mapping\nhappens).\n\n##### Use of expected type\n\nIf you would like that `json2typescript` performs an automatic type check according to given TypeScript types, you can\npass a type you expect. Follow the following guide when doing that:\n\n- Make sure you pass the class name and not an instance of the class.\n- In case of primitive types, you have to use the upper case names.\n- In case of `any` type, import from `json2typescript` the class `Any`.\n\nSee the following cheat sheet for reference:\n\n| Expected type             | TypeScript type       |\n| ---                       | ---                   |\n| String                    | string                |\n| Number                    | number                |\n| Boolean                   | boolean               | \n| User                      | User                  |\n| Any                       | any                   |\n|                           |                       | \n| [String]                  | string[]              | \n| [Number]                  | number[]              |\n| [Boolean]                 | boolean[]             | \n| [User]                    | User[]                | \n| [Any]                     | any[]                 | \n\nAt first, our array notation on the left looks odd. But this notation allows you to define even nested arrays. See the\nexamples at the end of this document for more info about nesting arrays.\n\n\u003e Tip: It is possible to lazy-load custom classes to prevent circular dependencies. \n\u003e Then, the expected type for custom classes can be written as a string. \n\u003e Please read further below how to implement this feature.\n\n##### Adding a custom converter\n\nMore advanced users may need to use custom converters. If you want\n`json2typescript` to use your custom converter, you need to follow these steps:\n\n- Write a converter class that implements `JsonCustomConvert\u003cT\u003e` where\n  `\u003cT\u003e` is the type resulting in the TypeScript class.\n- Make sure you add the `@JsonConverter` decorator to this class (see next chapter how).\n- Pass your converter class as second param in the `@JsonProperty` decorator\n\nAssume you would like to transform `1893-11-15` (string from JSON) to a TypeScript\n`Date` instance, then you would write a class `DateConverter` (see next chapter how)\nand pass it as second param in `@JsonProperty` as below:\n\n```typescript\n@JsonObject(\"User\")\nexport class User {\n    @JsonProperty(\"birthdate\", DateConverter)\n    birthdate: Date = new Date();\n}\n```\n\n#### Third parameter (optional): convertingMode\n\nThe third parameter of `@JsonProperty` determines how nullable property types should be serialized and deserialized.\nNullable types are either missing (in JSON), undefined (in TypeScript) or null (both). This parameter is optional; the\ndefault value is `PropertyConvertingMode.MAP_NULLABLE`.\n\nSee also the property `propertyConvertingMode` of the `JsonConvert` instance.\n\nThe values should be used as follows:\n\n- `PropertyConvertingMode.MAP_NULLABLE`: the mapper is applied, type is checked\n- `PropertyConvertingMode.IGNORE_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the\n  property is not added to the result\n- `PropertyConvertingMode.PASS_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the\n  property is added with its value to the result\n\n\u003e Tip: Make sure you import the `ENUM` `PropertyConvertingMode` when assigning a value to this property.\n\n##### Handling null, undefined and absent values\n\nBe careful when handling special values as `null`, `undefined` and `absent` properties.\n\nBy default, `json2typescript` throws an exception if a decorated class property cannot be found in the given JSON when\ndeserializing. If you set the third parameter to `IGNORE_NULLABLE` or `PASS_NULLABLE`, there will be no exception when\nit is missing. The type of a property will only be checked if the property is present in the JSON and not `undefined`\nor `null`.\n\nThe global setting of `valueCheckingMode` determines whether you want to allow `null` values for objects or properties.\nWe recommend to use the most strict option and also set your `TypeScript` compiler to the strict mode.\n\nThe following table explains the difference between the three property converting modes:\n\n| **ALLOW_NULL** | `serialize(null)` | `serialize(undefined)` | `deserialize(null)` | `deserialize(undefined)` |\n| ---                         | ---               | ---                    |  ---                | --- |\n| `MAP_NULLABLE`              | `null` | error | `null` | error |\n| `IGNORE_NULLABLE`           | `undefined` (missing) | `undefined` (missing) | default value | default value |\n| `PASS_NULLABLE`             | `null` | `undefined` (missing) | `null` | `undefined` |\n| |\n| **DISALLOW_NULL** | `serialize(null)` | `serialize(undefined)` | `deserialize(null)` | `deserialize(undefined)` |\n| `MAP_NULLABLE`              | error | error | error | error |\n| `IGNORE_NULLABLE`           | `undefined` (missing) | `undefined` (missing) | default value | default value |\n| `PASS_NULLABLE`             | `null` | `undefined` (missing) | `null` | `undefined` |\n\nAs shown in this table, a property with the default setting `MAP_NULLABLE` is never allowed to be `undefined` (or\nmissing). The `valueCheckingMode` determines, whether `null` is allowed.\n\n\u003e Tip: If you want `undefined` to be treated in the same way as `null` values, you may set the instance `mapUndefinedToNull` property to `true`.\n\n#### Important notes\n\n* Make sure you define the expected type as accurate as possible, even if you expect primitive types.\n* By default, casting primitives into other primitives is not allowed. Check the public properties below in this\n  document to change this behaviour.\n* By default, primitives are not allowed to be null. Check the public properties below in this document to change this.\n* If you don't know the type, you may use `Any` as expected type. You may also omit the second parameter\n  of `@JsonProperty`.\n\n#### More about the array syntax\n\n* You can allow arrays by using the bracket notation combined with the types as seen above. For example: `[String]` for\n  a string array\n* Mixing arrays is allowed. For example: `[String, Number]` for an array where the first entry is a string, the second\n  is a number.\n* If the real array is longer than indicated here, the last type will be forced to the rest of the array entries (\n  above: `Number`).\n* This means, `[String, Number]` is equivalent to `[String, Number, Number]` and so on.\n* Nesting arrays and objects are allowed. For example: `[[String, Number], User]`.\n* This is equivalent to `[[String, Number, Number], User, User]` and so on.\n* As further example, `[[String]]` is equal to `[[String],[String]]` which is equal\n  to  `[[String,String], [String,String]]` and so on.\n* If an array has less elements as given in the expected type, no exception is thrown.\n* For example, if we define `[String]` or the equivalent `[String, String]` no exception is thrown - even if the JSON\n  gives us an empty array.\n\n\u003e Tip: See the examples at the end of this document for advanced examples for nesting arrays.\n\n### Custom converter decorators\n\nIn some cases, you may need to make custom conversion between JSON objects and TypeScript objects. You can define custom\nconverters like this:\n\n```typescript\n@JsonConverter\nclass DateConverter implements JsonCustomConvert\u003cDate\u003e {\n    serialize(date: Date): any {\n        return date.getFullYear() + \"-\" + (date.getMonth() + 1) + \"-\" + date.getDate();\n    }\n\n    deserialize(date: any): Date {\n        return new Date(date);\n    }\n}\n```\n\n\u003e Tip: Make sure that you import `JsonConverter` from `json2typescript`. Also don't forget to use the same type between the brackets `\u003c\u003e`, as the `serialize()` param and `deserialize()` return value.\n\nAssume that in your JSON you have a date in a standardized format, such as `2017-07-19 10:00:00`. You could use the\ncustom converter class above to make sure it is stored as a real TypeScript `Date` in your class. For your property, you\nsimply have use the `@JsonProperty` decorator as follows:\n\n```typescript\n@JsonObject(\"User\")\nexport class User {\n    @JsonProperty(\"date\", DateConverter)\n    date: Date = new Date();\n}\n```\n\nWith this approach, you will achieve that your property `date` is going to be a real instance of `Date`.\n\n## JsonConvert class properties and methods\n\n### Public properties\n\n#### Operation mode\n\n`(number) JsonConvert.operationMode`\n\nDetermines how the JsonConvert class instance should operate.\n\nYou may assign three different values:\n\n- `OperationMode.DISABLE`: json2typescript will be disabled, no type checking or mapping is done\n- `OperationMode.ENABLE`: json2typescript is enabled, but only errors are logged\n- `OperationMode.LOGGING`: json2typescript is enabled and detailed information is logged\n\nThe default value is `OperationMode.ENABLE`. It will only print errors to the console and is suited for production.\n\nIn some cases, you might consider disabling `json2typescript` in production by setting the `OperationMode.DISABLE` flag.\nThis only works in case you only use plain objects without functionality and no mapping. However,\ndisabling `json2typescript` might give you a performance advantage in heavy projects.\n\nIn case you have issues to find bugs, you can enable additional logging by setting the `OperationMode.LOGGING` flag.\nPlease note that every serializing and deserializing is heavily logged to the console and will make your application\nslower. Never use this flag in production.\n\n\u003e Tip: Make sure you import the `ENUM` `OperationMode` when assigning a value to this property.\n\n#### Value checking mode\n\n`(number) JsonConvert.valueCheckingMode`\n\nDetermines which types are allowed to be null in the deserialization. You may assign three different values:\n\n* `ValueCheckingMode.ALLOW_NULL`: All given values can be null\n* `ValueCheckingMode.ALLOW_OBJECT_NULL`: Objects can be null, but primitive types cannot be null\n* `ValueCheckingMode.DISALLOW_NULL`: No null values are tolerated\n\nThe default is `ValueCheckingMode.ALLOW_OBJECT_NULL`.\n\n\u003e Tip: Make sure you import the `ENUM` `ValueCheckingMode` when assigning a value to this property.\n\n\u003e 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.\n\n#### Map undefined to null\n\n`(number) JsonConvert.mapUndefinedToNull`\n\nDetermines whether a missing or undefined property value should be considered as null or not.\n\nIf true, a missing JSON value will be added and set as null before deserialization. For serialization, undefined values\nwill be set to null before serialization.\n\n\u003e Note: ValueCheckingMode and PropertyConvertingMode determine whether an error will be thrown during serialization or deserialization.\n\n#### Ignore primitive checks\n\n`(bool) JsonConvert.ignorePrimitiveChecks`\n\nDetermines whether primitive types should be checked. If true, it will be allowed to assign primitive to other primitive\ntypes.\n\nThe default is `false`.\n\n#### Property matching rule\n\n`(number) JsonConvert.propertyMatchingRule`\n\nDetermines the rule of how JSON properties shall be matched with class properties during deserialization. You may assign\nthe following two values:\n\n* `PropertyMatchingRule.CASE_STRICT`: JSON properties need to match exactly the names in the decorators\n* `PropertyMatchingRule.CASE_INSENSITIVE`: JSON properties need to match names in the decorators, but names they are not\n  case sensitive\n\nThe default is `PropertyMatchingRule.CASE_STRICT`.\n\n#### Property converting mode\n\n`(number|undefined) JsonConvert.propertyConvertingMode`\n\nDetermines how nullable property types should be serialized and deserialized. Nullable types are either missing (in\nJSON), undefined (in TypeScript) or null (both).\n\nIf the propertyConvertingMode has a non-undefined value, it overrides the individual settings of every property. See\nalso the third parameter of the `@JsonProperty` decorator.\n\nThe values should be used as follows:\n\n- `PropertyConvertingMode.MAP_NULLABLE`: the mapper is applied, type is checked\n- `PropertyConvertingMode.IGNORE_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the\n  property is\n    * not added to the result\n- `PropertyConvertingMode.PASS_NULLABLE`: the mapper is not applied if the property is missing, undefined or null; the\n  property is\n    * added with its value to the result\n\nThe default is `PropertyMatchingRule.MAP_NULLABLE`.\n\n\u003e Note: This property is usually only temporarily set and should be used with caution.\n\u003e It replaces the deprecated property `ignoreRequiredCheck`.\n\n#### Use discriminator\n\n`(bool) JsonConvert.useDiscriminator`\n\nDetermines if discriminators should be used.\nIf 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. \nWhen 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).\n\nThe default is `false`.\n\n\u003e Note: At the end of this document you may find an example on how to use the discriminator feature.\n\n#### Discriminator property name\n\n`(string) JsonConvert.discriminatorPropertyName`\n\nDefines the name of the discriminator property.\n\nThe default is `\"$type\"`.\n\n\n### Public methods\n\n`json2typescript` allows you to map JSON objects (or arrays) to TypeScript objects (or arrays) and vice versa.\n\n#### Serializing (TypeScript to JSON)\n\n`(any|any[]) serialize\u003cT extends object, U extends object = {}\u003e(data: T | T[], classReference?: { new(): U })`\n\nTries to serialize a TypeScript object or array of objects to JSON.\n\nThe first parameter must be a TypeScript object or array, the second parameter is the optional class reference.\n\nIf you provide only one parameter, the class for serialization is inferred automatically. For example, if you\ncall `jsonConvert.serialize(user)` where `user` is an instance of the class `User`, `json2typescript` will automatically\nuse this class for serialization.\n\nBy providing two parameters, it will override the class for serialization. For example, this allows you to\ncall `jsonConvert.serialize(userObject, User)` where `userObject` is just a plain TypeScript `any` object.\n\nThe returned value will be `any` object or an array of `any` objects.\n\n\u003e Tip: The return value is not a string. In case you need a string as result, use `JSON.stringify()` after calling the serialize method.\n\nYou may optionally provide a class constructor to use the `@JsonProperty` mappings defined for that class to serialize\nthe data object(s), instead of mappings defined on the data class. Note that if the data is an array, the mappings from\nthe constructor class are used for *all* elements in the array. If no constructor is provided, the mappings from the\ndata object class are used to serialize the data object(s).\n\n\u003e 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.\n\n#### Deserializing (JSON to TypeScript)\n\n`(T | T[]) deserialize\u003cT extends object\u003e(json: any, classReference: { new(): T } | null = null)`\n\nTries to deserialize given JSON to a TypeScript object or array of objects.\n\nThe first parameter must be a Typescript object or array, the second parameter is the class reference.\nIf the discriminator feature is used, the class reference is optional.\n\nThe returned value will be an instance or an array of instances of the given class reference.\n\n\u003e 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.\n\n#### Registering and unregistering classes\n\n`void registerClasses(...classReferences: { new(): any }[])`\n\nRegisters a list of classes to be used with lazy-loading and in the discriminator feature.\n\n`void ungisterClasses(...classReferences: { new(): any }[])`\n\nUnregisters a list of classes from lazy-loading and the discriminator feature.\n\n`void unregisterAllClasses()`\n\nUnregisters all classes from lazy-loading and the discriminator feature.\n\n\u003e Note: You only need to register and unregister classes if you use lazy-loading or the discriminator feature. Otherwise, these methods are without any effect.\n\n#### Other methods\n\nThe methods `serialize()` and `deserialize()` will automatically detect the dimension of your param (either object or\narray). In case you would like to force `json2typescript` to use a specific way, you can use the following methods\ninstead:\n\n- `(any) serializeObject\u003cT extends object, U extends object = {}\u003e(data: T, classReference?: { new(): U })`\n- `(any[]) serializeArray\u003cT extends object, U extends object = {}\u003e(dataArray: T[], classReference?: { new(): U })`\n- `(T) deserializeObject\u003cT extends object\u003e(jsonObject: any, classReference: { new(): T })`\n- `(T[]) deserializeArray\u003cT extends object\u003e(jsonArray: any[], classReference: { new(): T })`\n\n\n\n---\n\n# Advanced strategies\n\nIn this section you will find additional examples.\n\n## Nesting arrays\n\nIt is heavily discouraged to use nested arrays and use different types in a JSON API. If you need them anyway, here is\nhow you have to define the types:\n\n### 1) Nested arrays with same type\n\nIn the following example, `jsonKeyOfWeirdKeywords` is a key in the JSON object defined like this:\n\n```JSON\n{\n  \"jsonKeyOfWeirdKeywords\": [\n    [\n      \"Hello\",\n      \"World\"\n    ],\n    [\n      \"Bye\",\n      \"Earth\"\n    ]\n  ]\n}\n```\n\nAs we have an array of array of strings, you can define the expected type like this:\n\n```typescript\n@JsonObject(\"User\")\nexport class User {\n    @JsonProperty(\"jsonKeyOfWeirdKeywords\", [[String, String], [String, String]])\n    keywords: (string[])[] = [];\n}\n```\n\n\u003e Tip: In our syntax, `[[String, String], [String, String]]` is equivalent to `[[String], [String]]` and `[[String]]`. That is because the last type in an array will be automatically repeated as much as needed.\n\n### 2) Nested array with mixed depth and type\n\nIn the following example, `JSONKeyOfWeirdKeywords` is a key in the JSON object defined like this:\n\n```JSON\n{\n  \"jsonKeyOfWeirdKeywords\": [\n    [\n      \"FC\",\n      \"Basel\"\n    ],\n    1893\n  ]\n}\n```\n\nYou can define the expected type in your class like this:\n\n```typescript\n@JsonObject(\"User\")\nexport class User {\n    @JsonProperty(\"jsonKeyOfWeirdKeywords\", [[String, String], Number])\n    keywords: (string[] | number)[] = [];\n}\n```\n\n\u003e Tip: In our syntax, `[[String, String], Number]` is equivalent to `[[String], Number]`.\n\n## Instantiation with the lazy-loading feature to avoid circular dependencies\n\nIn some scenarios, developers run into circular dependencies when declaring objects. \nA simple example would be two classes importing each other:\n\n```typescript\nimport { User } from \"./user\";\n\n@JsonObject(\"Team\")\nexport class Team {\n    @JsonProperty(\"users\", [User])\n    user: User[] = [];\n}\n```\n\n```typescript\nimport { Team } from \"./team\";\n\n@JsonObject(\"User\")\nexport class User {\n    @JsonProperty(\"teams\", [Team])\n    team: Team[] = [];\n}\n```\n\nThis is generally not possible because of the circular dependency.\nBut since TypeScript 3.8, you may use [type imports](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html) in order to bypass circular dependencies.\n\n`json2typescript` implements a lazy-loading feature so that the above example is possible.\nThe following steps need to be done:\n- Import only the type, for example by writing `import type { User } from \"./user\";`. Note that we added the `type` keyword.\n- Do not use the class reference in the `@JsonProperty` decorator, but instead use the classIdentifier (as string) given in the `@JsonObject` decorator.\nFor example, write `@JsonProperty(\"users\", [\"User\"])`. Note that we added the `\"` around the User.\n- Register all lazy-loading classes before ever using them with `json2typescript`. \nYou may simply call `jsonConvert.registerClasses(User, Team)` for the example above.\n\nNow you can use the classes `User` and `Team` as expected.\n\n\u003e Note: Using type imports may cause other problems in your classes because the imports may only be used for type contexts.\n\u003e For example, you will not be able to write `new Team()` in the `User` class at all.\n\u003e However, you still will be able to use `Team` as a type in the `User` class and access all its properties and methods.\n\n## Automatic instantiation using the discriminator feature\n\nIf your server adds a discriminator property to every JSON object, `json2typescript` is able to automatically instantiate objects.\n\nFirst, set up the discriminator feature for a class, for example\n\n```typescript\n@JsonObject(\"app.example.User\")\nexport class User {\n    @JsonProperty(\"name\", String)\n    name: string = \"\";\n}\n```\n\nNow, set up a `JsonConvert` to enable the discriminator feature and activate it for the classes you like:\n\n```typescript\n// Set up json convert\nlet jsonConvert: JsonConvert = new JsonConvert();\njsonConvert.useDiscriminator = true; // enable the discriminator\njsonConvert.discriminatorPropertyName = \"$type\"; // this is the property name\njsonConvert.registerClasses(User); // register all classes\n\n// Assume the following JSON object coming from your server\nconst jsonObject: any = {\n    \"name\": \"Walter\",\n    \"$type\": \"app.example.User\" // the value of $type matches the @JsonObject decorator above\n}\n\n// This is how you would traditionally map an object\n// But we have enabled the discriminator functionality and registered the User class\n// In that case, the second parameter (User) here is ignored\nconst user1: User = jsonConvert.deserialize(jsonObject, User);\n\n// But now you may automatically map it thanks to the $type property\nconst user2: User = jsonConvert.deserialize\u003cUser\u003e(jsonObject);\n```\n\n\u003e Note: This feature is particularly useful when doing dynamic mapping. \n\u003e Otherwise, you just may provide the type yourself (as done above with `user1`) and disable the discriminator feature.\n\nA real-world example for the discriminator feature is the mapping of child classes.\n\nAssume that you might have two classes `AdminUser` and `NormalUser` that inherit from `User`. \nThe web client sometimes cannot know the type in advance. \nIf you use the discriminator feature, the server can define the type in the JSON and `json2typescript` will properly instantiate the desired class.\nThis means, your property can be safely declared in TypeScript as union type of `AdminUser | NormalUser` instead of `User`.\n\n\u003e 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.\n\n\n\n---\n\n# Tools\n\n## Class decorator generator\n\nSince version 1.4, `json2typescript` requires the `@JsonObject(\"ClassName\")` decorator in front of the TypeScript class\ndefinition. GitHub user `tlmurphy` created a Python script that automatically generates the decorator with the original\nclass name as parameter.\n\nMore: https://gist.github.com/tlmurphy/71b58c71e594899120da365159d7d40d\n\n---\n\n# Contributors\n\nThis NPM package was originally created in 2016 by **Andreas Aeschlimann**, founder of and software architect at **AppVision GmbH**.\n\n## Special thanks\n\nYou are welcome to report issues and discuss enhancements to make this package even more useful. Thanks for the input\nand all the pull requests from the community!\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAppVision-GmbH%2Fjson2typescript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAppVision-GmbH%2Fjson2typescript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAppVision-GmbH%2Fjson2typescript/lists"}