{"id":13660664,"url":"https://github.com/danrevah/typeserializer","last_synced_at":"2025-06-21T13:37:58.517Z","repository":{"id":26902171,"uuid":"111861854","full_name":"danrevah/typeserializer","owner":"danrevah","description":":tada: Awesome serializer / deserializer for javascript objects","archived":false,"fork":false,"pushed_at":"2022-02-11T04:58:13.000Z","size":549,"stargazers_count":108,"open_issues_count":8,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-06-09T04:46:13.006Z","etag":null,"topics":["angular","javascript","js","node","nodejs","react","serializer","ts","typescript","vue"],"latest_commit_sha":null,"homepage":"","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/danrevah.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-24T00:56:53.000Z","updated_at":"2025-06-06T16:46:47.000Z","dependencies_parsed_at":"2022-07-27T09:02:37.320Z","dependency_job_id":null,"html_url":"https://github.com/danrevah/typeserializer","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/danrevah/typeserializer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danrevah%2Ftypeserializer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danrevah%2Ftypeserializer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danrevah%2Ftypeserializer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danrevah%2Ftypeserializer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danrevah","download_url":"https://codeload.github.com/danrevah/typeserializer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danrevah%2Ftypeserializer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261130455,"owners_count":23114000,"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","javascript","js","node","nodejs","react","serializer","ts","typescript","vue"],"created_at":"2024-08-02T05:01:24.314Z","updated_at":"2025-06-21T13:37:53.498Z","avatar_url":"https://github.com/danrevah.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# TypeSerializer\n\n\u003cp align=\"center\"\u003e\n\u003cbr/\u003e\n\u003ca href=\"https://www.npmjs.com/package/typeserializer\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/typeserializer.svg?style=flat-square\" alt=\"npm\"\u003e\u003c/a\u003e\n\u003ca href=\"https://travis-ci.org/danrevah/typeserializer\"\u003e\u003cimg src=\"https://travis-ci.org/danrevah/typeserializer.svg?branch=master\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003ca href='https://coveralls.io/github/danrevah/typeserializer'\u003e\u003cimg src='https://coveralls.io/repos/github/danrevah/typeserializer/badge.svg' alt='Coverage Status' /\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/danrevah/typeserializer/blob/master/LICENSE.md\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square\" alt=\"MIT licensed\"\u003e\u003c/a\u003e\n\u003cbr/\u003e\u003cbr/\u003e\nSerializer / deserializer of javascript objects\n\u003cbr/\u003e\u003cbr/\u003e\n\u003c/p\u003e \n\n## Table of contents\n\n - [Installation](#installation)\n - [Decorators](#decorators)\n    - [Exclude](#exclude)\n    - [Expose](#expose)\n    - [Name](#name)\n    - [Groups](#groups)\n    - [Version](#version)\n    - [Type](#type)\n - [Deep Objects](#deep-objects)\n - [Custom Deserializer](#custom-deserializer)\n - [Custom Serializer](#custom-serializer)\n\n## Installation\n\n1. Install using npm: \n\n```\n $ npm install typeserializer --save\n```\n\n2. You also need to install reflect-metadata shim:\n\n```\n $ npm install reflect-metadata --save\n```\n\n3. Import `reflect-metadata` in a global place of your app (for ex. index.ts):\n\n```typescript\nimport 'reflect-metadata';\n```\n\n### Decorators\n\n#### Exclude\n \n While using the default manual exclude you only need to decorate the properties you like to exclude with `@Exclude`.\n This will cause the property to be EXCLUDED from the response.\n \n \n```typescript\n import {serialize, Exclude} from 'typeserializer';\n\n class User {\n \n   name = 'dan';\n   \n   @Exclude()\n   password = '123456';\n }\n \n const user = new User();\n console.log(serialize(user)); // prints: '{ name: 'dan' }'\n````\n\n#### Expose\n \n Using `all` as the exclusion strategy will exclude all properties except for those marked as `@Expose()`.\n \n```typescript\n import {serialize, Expose, Strategy, ExclusionPolicy} from 'typeserializer';\n\n @Strategy(ExclusionPolicy.ALL) // \u003c-- This is Required!\n class User {\n   @Expose()\n   name = 'dan';\n   \n   password = '123456';\n }\n \n const user = new User();\n console.log(serialize(user)); // prints: '{ name: 'dan' }'\n````\n\n#### Expose - Dynamic Exclusion\n\nIf you would like to use a dynamic approach as an exclusion strategy, you can also make use of the dynamic exclusion capability.\n\n```typescript\nimport {Strategy, Expose, ExclusionPolicy, serialize} from 'typeserializer';\n\n function validator(object: any, propertyKey: string) {\n   return object[propertyKey] \u003e 5;\n }\n \n@Strategy(ExclusionPolicy.ALL)\n class Foo {\n \n   @Expose(validator)\n   prop = 1;\n \n   @Expose(validator)\n   prop2 = 10;\n \n   @Expose(validator)\n   prop3 = 8;\n }\n \n const foo = new Foo();\n console.log(serialize(foo)); // prints: '{ prop2: 10, prop3: 8 }'\n``` \n\n#### Name\n\nChanging name of a selected property is supported by using the `@Name` decorator.\n\n```typescript\n import {serialize, Name} from 'typeserializer';\n\n class User {\n \n   @Name('name')\n   myName = 'dan';\n   \n }\n \n const user = new User();\n console.log(serialize(user)); // prints: '{ name: 'dan' }'\n````\n\n#### Groups\n \n You can expose different properties by using the `@Groups` annotation.\n \n```typescript\n import {Strategy, Expose, ExclusionPolicy, Groups, serialize} from 'typeserializer';\n\n @Strategy(ExclusionPolicy.ALL)\n class User {\n \n   @Expose()\n   @Groups(['user-account'])\n   username = 'Dan';\n \n   @Expose()\n   @Groups(['user-details'])\n   age = 28;\n \n   password = 'foo';\n }\n \n const user = new User();\n console.log(serialize(user)); // prints: '{ username: 'Dan', age: 28 }'\n console.log(serialize(user, ['user-account'])); // prints: '{ username: 'Dan' }'\n console.log(serialize(user, ['user-details'])); // prints: '{ age: 28 }'\n console.log(serialize(user, ['user-account', 'user-details'])); // prints: '{ username: 'Dan', age: 28 }'\n````\n\n### Deep Objects\n\nTypeSerializer can also serialize objects deeply.\n\n```typescript\n import {Strategy, Expose, ExclusionPolicy, Groups, serialize} from 'typeserializer';\n\n@Strategy(ExclusionPolicy.ALL)\nclass UserDetails {\n\n  @Expose()\n  @Groups(['name'])\n  firstName = 'Dan';\n\n  @Expose()\n  @Groups(['name'])\n  lastName = 'Revah';\n\n  @Expose()\n  @Groups(['other'])\n  age = 28; \n}\n\n@Strategy(ExclusionPolicy.ALL)\n class User {\n \n   @Expose()\n   @Groups(['user-account'])\n   username = 'Dan';\n \n   @Expose()\n   @Groups(['user-details'])\n   details = new UserDetails();\n \n   password = 'foo';\n }\n \n const user = new User();\n console.log(serialize(user, ['user-details'])); // prints: { details: { firstName: 'Dan', lastName: 'Revah', age: 28 } }\n console.log(serialize(user, ['user-details', 'name'])); // prints: { details: { firstName: 'Dan', lastName: 'Revah' } }\n console.log(serialize(user, ['user-details', 'other'])); // prints: { details: { age: 28 } }\n```\n\n#### Version\n\nYou can also serialize a property by version number with @Before \u0026 @After.\n\n```typescript\n import {Strategy, Expose, ExclusionPolicy, serialize, Before, After} from 'typeserializer';\n\n@Strategy(ExclusionPolicy.ALL)\n class UserDetails {\n \n   @Expose()\n   @Before('1.2.0')\n   firstName = 'Dan';\n \n   @Expose()\n   @Before('1.2.0')\n   lastName = 'Revah';\n \n   @Expose()\n   @After('1.2.0')\n   fullName = 'Dan Revah';\n }\n \n const user = new UserDetails();\n console.log(serialize(user)); // prints: '{ firstName: 'Dan', lastName: 'Revah', fullName: 'Dan Revah' }'\n \n console.log(serialize(user, [], '0.4.2')); // prints: '{ firstName: 'Dan', lastName: 'Revah' }'\n console.log(serialize(user, [], '1.1.9')); // prints: '{ firstName: 'Dan', lastName: 'Revah' }'\n \n console.log(serialize(user, [], '1.2.0')); // prints: '{ fullName: 'Dan Revah' }'\n console.log(serialize(user, [], '1.3.0')); // prints: '{ fullName: 'Dan Revah' }'\n```\n\n#### Type\n\nTypeSerializer also contains a `deserialize()` method, to deserialize JSON to objects.\n\nSince TypeScript doesn't transpiles types, it is a requirement to add `@Type` annotation for the 'complex' type properties, including JavaScript's `Date`.  \n\nThis is very useful when you are getting a JSON string, and you know it's of a certain type.\n\n\n```typescript\nimport {deserialize, Type} from 'typeserializer';\n\nconst fixtureSimple =\n  '{\"firstName\":\"Dan\",\"lastName\":\"Revah\",\"age\":28,\"isHere\":true,\"birthDate\":\"2018-07-15T05:35:03.000Z\"}';\n  \nconst fixtureChild = `{\"child\":${fixtureSimple}}`;\nconst fixtureChildren = `{\"children\":[${fixtureSimple}, ${fixtureSimple}]}`;\n\nclass Simple {\n  firstName: string;\n  lastName: string;\n  age: number;\n  isHere: boolean;\n\n  @Type(Date)\n  birthDate: Date;\n  \n  getFullName() {\n    return `${this.firstName} ${this.lastName}`;\n  }\n}\n\nclass SimpleChild {\n  @Type(Simple) \n  child: Simple;\n}\n\nclass SimpleChildArr {\n  @Type([Simple])  // You must wrap with '[]' when defining an array of a type.\n  children: Simple[];\n}\n\nconst simple: Simple = deserialize(fixtureSimple, Simple);\n\n console.log(simple); // Simple { firstName: \"Dan\", ... }\n console.log(simple.getFullName()); // Now you can even use class methods! -\u003e Prints 'Dan Revah'. \n \n\n console.log(deserialize(fixtureChild, SimpleChild)); // SimpleChild { child: Simple { firstName: \"Dan\", ... } }\n console.log(deserialize(fixtureChildren, SimpleChildArr)); // SimpleChildArr { children: [Simple { ... }, Simple { ... }] }\n\n``` \n\n#### Custom Deserializer\n\nIt's also possible to use a custom deserializer, in-case you have any 'special' types you want to handle.\n\nFor example you could deserialize *to* a Moment instance using the `@Deserializer()` annotation.\n\n```typescript\nimport {Deserializer, deserialize} from 'typeserializer';\n\nconst fixture = '{\"date\":\"2012-12-21T00:00:00\"}';\n\nclass Foo {\n  @Deserializer((m: string): any =\u003e Moment(m))\n  date: Moment;\n  \n  getDate() {\n    return this.date.format('DD-MM-YYYY');  \n  }\n  \n}\n\nconst foo: Foo = deserialize(fixture, Foo);\n\nconsole.log(foo.getDate()); // '21-12-2012'\n``` \n\n#### Custom Serializer\n\nIt's also possible to use a custom serializer, in-case you have any 'special' types you want to handle.\n\nFor example you could serialize *from* a Moment instance using the `@Serializer()` annotation.\n\n```typescript\nimport {Serializer, serialize} from 'typeserializer';\n\nclass Bar {\n  @Serializer((m: Moment): any =\u003e m.format('DD-MM-YYYY'))\n  date: Moment;\n}\n\nconst bar: Bar = new Bar();\n\nbar.date = Moment('2012-12-21T00:00:00');\n\nconsole.log(serialize(bar)); // {\"date\":\"21-12-2012\"}\n``` \n\nAnd ofcourse this can be combined with the previous custom Deserializer:\n```typescript\nimport {Serializer, serialize} from 'typeserializer';\n\nclass Bar {\n  @Deserializer((m: string): any =\u003e Moment(m))\n  @Serializer((m: Moment): any =\u003e m.format('DD-MM-YYYY'))\n  date: Moment;\n}\n\nconst bar: Bar = new Bar();\nbar.date = Moment('2012-12-21T00:00:00');\nconst json = serialize(bar);\nconsole.log(json); // {\"date\":\"21-12-2012\"}\n\nconst bar2: Bar = deserialize(json, Bar);\nconsole.log(bar2.getDate()); // '21-12-2012'\n\n``` \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanrevah%2Ftypeserializer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanrevah%2Ftypeserializer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanrevah%2Ftypeserializer/lists"}