{"id":11169,"library":"jsog-typescript","title":"JSOG for TypeScript","description":"jsog-typescript is a TypeScript module that implements the JavaScript Object Graph (JSOG) format, enabling the serialization and deserialization of JavaScript objects while preserving object references to prevent cycles and duplicates. Its key differentiator is the ability to instantiate actual TypeScript class instances during deserialization, leveraging decorators for type mapping. This allows developers to work with rich object models that retain their methods and `typeof` information after being processed. The package is currently at version 1.0.0-1 and appears to be actively maintained, offering specific integration patterns for frameworks like Angular 4 and AngularJS. It builds upon the core JSOG specification and incorporates ideas from `json-typescript-mapper` to provide this type-aware deserialization.","status":"active","version":"1.0.0-1","language":"javascript","source_language":"en","source_url":"https://github.com/e-mundo/jsog-typescript","tags":["javascript","typescript","jsog","npm"],"install":[{"cmd":"npm install jsog-typescript","lang":"bash","label":"npm"},{"cmd":"yarn add jsog-typescript","lang":"bash","label":"yarn"},{"cmd":"pnpm add jsog-typescript","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required at runtime for TypeScript's experimental decorators and emitDecoratorMetadata compiler option to function, enabling class property type inference.","package":"reflect-metadata","optional":false}],"imports":[{"note":"This is a pre-instantiated singleton service suitable for most basic serialization and deserialization tasks.","wrong":"const jsogService = require('jsog-typescript').jsogService;","symbol":"jsogService","correct":"import { jsogService } from 'jsog-typescript'"},{"note":"Import the class directly to create new instances, for example, when integrating into dependency injection frameworks like Angular or for custom configurations.","wrong":"import JsogService from 'jsog-typescript';","symbol":"JsogService","correct":"import { JsogService } from 'jsog-typescript'"},{"note":"The `@JsonProperty()` decorator is crucial for enabling type-aware deserialization, mapping JSON properties to TypeScript class properties. It can also accept a class type for properties that are arrays of custom objects.","wrong":"import { JsonProperty } from 'jsog-typescript/decorators';","symbol":"JsonProperty","correct":"import { JsonProperty } from 'jsog-typescript'"}],"quickstart":{"code":"import { jsogService, JsonProperty, JsogService } from 'jsog-typescript';\nimport 'reflect-metadata'; // Essential for decorators to work at runtime\n\n// 1. Define a TypeScript class with decorators\nclass Address {\n  @JsonProperty() street: string = '';\n  @JsonProperty() city: string = '';\n\n  getFullAddress(): string {\n    return `${this.street}, ${this.city}`;\n  }\n}\n\nclass Person {\n  @JsonProperty() id: number = 0;\n  @JsonProperty() name: string = '';\n  @JsonProperty(Address) address: Address | undefined;\n  @JsonProperty(Person) friends: Person[] = []; // Array of nested custom objects\n\n  greet(): string {\n    return `Hello, my name is ${this.name}!`;\n  }\n}\n\n// 2. Instantiate and serialize an object graph\nconst person1 = new Person();\nperson1.id = 1;\nperson1.name = 'Alice';\nperson1.address = new Address();\nperson1.address.street = '123 Main St';\nperson1.address.city = 'Anytown';\n\nconst person2 = new Person();\nperson2.id = 2;\nperson2.name = 'Bob';\nperson2.friends.push(person1); // Create a circular reference\n\nperson1.friends.push(person2);\n\nconst serializedGraph = jsogService.serialize(person1);\nconsole.log('Serialized Graph:', JSON.stringify(serializedGraph, null, 2));\n\n// 3. Deserialize back into TypeScript objects\nconst deserializedPerson = jsogService.deserializeObject(serializedGraph, Person);\n\nconsole.log('\\nDeserialized Person:', deserializedPerson);\nconsole.log('Is instance of Person:', deserializedPerson instanceof Person); // true\nconsole.log('Is instance of Address:', deserializedPerson.address instanceof Address); // true\nconsole.log('Person greeting:', deserializedPerson.greet());\nconsole.log('Person address:', deserializedPerson.address?.getFullAddress());\nconsole.log('Friend greeting:', deserializedPerson.friends[0]?.greet());\n","lang":"typescript","description":"This quickstart demonstrates defining TypeScript classes with `@JsonProperty` decorators, serializing an object graph including circular references, and then deserializing it back into full TypeScript class instances, preserving methods and `instanceof` checks."},"warnings":[{"fix":"Add `\"experimentalDecorators\": true, \"emitDecoratorMetadata\": true` to the `compilerOptions` section of your `tsconfig.json`.","message":"Enabling TypeScript's `experimentalDecorators` and `emitDecoratorMetadata` compiler options is mandatory for this library to function correctly at compile time.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Install `reflect-metadata` (`npm install reflect-metadata`) and add `import 'reflect-metadata';` at the very top of your application's main entry point (e.g., `main.ts` or `index.ts`).","message":"The `reflect-metadata` package is a required runtime dependency for `emitDecoratorMetadata` to provide type information at runtime. Without it, deserialization into specific TypeScript classes will fail silently or with runtime errors.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"For properties that are a single custom object, use `@JsonProperty(MyClass)`. For properties that are arrays of custom objects, use `@JsonProperty(MyClass)` on the array property itself.","message":"For complex nested objects or arrays of custom types, the `@JsonProperty` decorator requires a type argument to correctly instantiate objects during deserialization.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If your class requires constructor arguments, consider providing a default constructor or ensuring your class design allows for no-argument instantiation when deserialized by `jsog-typescript`.","message":"When deserializing to a specific TypeScript class, ensure that the class has a default (no-argument) constructor, or that the library can infer how to instantiate it. Missing default constructors can lead to errors.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Run `npm install reflect-metadata` and add `import 'reflect-metadata';` as the very first line in your main application entry file (e.g., `main.ts`).","cause":"The `reflect-metadata` polyfill is missing or not imported at the application's entry point, which is crucial for TypeScript decorators to emit and retrieve type metadata at runtime.","error":"ReferenceError: Reflect is not defined"},{"fix":"Verify that `experimentalDecorators` and `emitDecoratorMetadata` are enabled in `tsconfig.json` and that all properties intended for deserialization into custom types have the `@JsonProperty()` decorator, with type arguments where necessary (e.g., `@JsonProperty(MyClass)`).","cause":"During `deserializeObject` or `deserializeArray`, `jsog-typescript` failed to instantiate the target TypeScript class, often because of missing decorators or incorrect `tsconfig.json` settings.","error":"Error: Cannot convert object with JSOG ID to class. [class name] expected."},{"fix":"Ensure you are using `jsog.deserializeObject(data, MyClass)` or `jsog.deserializeArray(data, MyClass)` to explicitly tell `jsog-typescript` to instantiate objects as `MyClass` instances, and that `reflect-metadata` is properly imported.","cause":"While the object might look correct, it was likely deserialized as a plain JavaScript object or an incorrect type, meaning methods defined on your TypeScript class are not available.","error":"Property 'someMethod' does not exist on type 'MyClass' after deserialization."}],"ecosystem":"npm"}