Sérialisation d'objets en TypeScript : de JSON à protobuf
La sérialisation est le processus de conversion d'une structure de données complexe (objet, tableau, instance de classe) en un format adapté au stockage ou à la transmission sur un réseau. Le processus inverse — la désérialisation — reconstruit l'objet à partir de ce format. En TypeScript, qui est un sur-ensemble strictement typé de JavaScript, la sérialisation revêt une importance particulière : il est crucial non seulement de transmettre les données, mais aussi de préserver les types, les méthodes et la structure des classes.
Dans cet article, nous examinerons les principales approches et outils pour la sérialisation d'objets en TypeScript, des fonctionnalités intégrées aux bibliothèques spécialisées.
1. Sérialisation native : JSON.stringify et JSON.parse
La méthode la plus simple et la plus courante consiste à utiliser les méthodes intégrées JSON.stringify() et JSON.parse(). Cependant, cette approche présente des limitations :
- Les fonctions,
undefined,Symbol,BigInt(dans les anciennes versions) ne sont pas sérialisées. - Le prototype de l'objet n'est pas conservé — lors de la désérialisation, vous obtenez un objet ordinaire, et non une instance de classe.
- Les références circulaires provoquent une erreur.
// Exemple de sérialisation simpleinterface User { id: number; name: string; email: string;}
const user: User = { id: 1, name: "Иван", email: "ivan@example.com"};
const jsonString = JSON.stringify(user);console.log(jsonString); // {"id":1,"name":"Иван","email":"ivan@example.com"}
const parsedUser: User = JSON.parse(jsonString);console.log(parsedUser.name); // ИванPour des données simples, cela suffit, mais si vous devez travailler avec des classes, une solution plus avancée est nécessaire.
2. Sérialisation personnalisée avec les méthodes toJSON et fromJSON
TypeScript (et JavaScript) permet de définir dans une classe la méthode toJSON(), qui sera appelée lors de la sérialisation via JSON.stringify. Pour la désérialisation, vous pouvez créer une méthode statique fromJSON.
class Person { constructor( public firstName: string, public lastName: string, public age: number ) {}
// Méthode de sérialisation toJSON() { return { fullName: `${this.firstName} ${this.lastName}`, age: this.age }; }
// Méthode statique de désérialisation static fromJSON(json: any): Person { const [firstName, lastName] = json.fullName.split(' '); return new Person(firstName, lastName, json.age); }}
const person = new Person("Анна", "Петрова", 30);const json = JSON.stringify(person);console.log(json); // {"fullName":"Анна Петрова","age":30}
const restoredPerson = Person.fromJSON(JSON.parse(json));console.log(restoredPerson.firstName); // АннаCette approche offre un contrôle total, mais nécessite d'écrire du code standard pour chaque classe.
3. Bibliothèque class-transformer
class-transformer est l'une des bibliothèques les plus populaires pour la sérialisation/désérialisation en TypeScript. Elle permet de convertir des objets ordinaires en instances de classes et vice versa à l'aide de décorateurs.
Installation :
npm install class-transformer reflect-metadataExemple d'utilisation :
import { plainToClass, classToPlain, Expose, Transform } from "class-transformer";import "reflect-metadata";
class Product { @Expose() id: number;
@Expose() name: string;
@Expose() @Transform(({ value }) => value.toUpperCase()) // transformation personnalisée category: string;
@Expose({ name: "price_with_tax" }) // renommage du champ price: number;
constructor(id: number, name: string, category: string, price: number) { this.id = id; this.name = name; this.category = category; this.price = price; }
getInfo(): string { return `${this.name} (${th