Serialización de objetos en TypeScript: de JSON a protobuf
La serialización es el proceso de convertir una estructura de datos compleja (objeto, arreglo, instancia de clase) en un formato adecuado para almacenamiento o transmisión a través de la red. El proceso inverso, la deserialización, restaura el objeto a partir de ese formato. En TypeScript, que es una extensión fuertemente tipada sobre JavaScript, la serialización adquiere especial importancia: no solo es importante transmitir datos, sino también conservar los tipos, métodos y la estructura de las clases.
En este artículo, exploraremos los enfoques y herramientas principales para la serialización de objetos en TypeScript, desde las capacidades integradas hasta bibliotecas especializadas.
1. Serialización nativa: JSON.stringify y JSON.parse
La forma más simple y común es usar los métodos integrados JSON.stringify() y JSON.parse(). Sin embargo, este enfoque tiene limitaciones:
- No serializa funciones,
undefined,Symbol,BigInt(en versiones antiguas). - No conserva el prototipo del objeto: al deserializar obtendrá un objeto plano, no una instancia de clase.
- Las referencias circulares generan un error.
// Ejemplo de serialización simpleinterface User { id: number; name: string; email: string;}
const user: User = { id: 1, name: "Iván", email: "ivan@example.com"};
const jsonString = JSON.stringify(user);console.log(jsonString); // {"id":1,"name":"Iván","email":"ivan@example.com"}
const parsedUser: User = JSON.parse(jsonString);console.log(parsedUser.name); // IvánPara datos simples esto es suficiente, pero si necesita trabajar con clases, necesitará una solución más avanzada.
2. Serialización personalizada con métodos toJSON y fromJSON
TypeScript (y JavaScript) permite definir en una clase el método toJSON(), que se llamará al serializar mediante JSON.stringify. Para la deserialización, puede crear un método estático fromJSON.
class Person { constructor( public firstName: string, public lastName: string, public age: number ) {}
// Método para serialización toJSON() { return { fullName: `${this.firstName} ${this.lastName}`, age: this.age }; }
// Método estático para deserialización static fromJSON(json: any): Person { const [firstName, lastName] = json.fullName.split(' '); return new Person(firstName, lastName, json.age); }}
const person = new Person("Ana", "Petrova", 30);const json = JSON.stringify(person);console.log(json); // {"fullName":"Ana Petrova","age":30}
const restoredPerson = Person.fromJSON(JSON.parse(json));console.log(restoredPerson.firstName); // AnaEste enfoque brinda control total, pero requiere escribir código repetitivo para cada clase.
3. Biblioteca class-transformer
class-transformer es una de las bibliotecas más populares para serialización/deserialización en TypeScript. Permite convertir objetos planos en instancias de clase y viceversa usando decoradores.
Instalación:
npm install class-transformer reflect-metadataEjemplo de uso:
import { plainToClass, classToPlain, Expose, Transform } from "class-transformer";import "reflect-metadata";
class Product { @Expose() id: number;
@Expose() name: string;
@Expose() @Transform(({ value }) => value.toUpperCase()) // transformación personalizada category: string;
@Expose({ name: "price_with_tax" }) // renombrar campo 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 También en la biblioteca
Generación de informes PDF en C++: biblioteca libHaru
Supertest para JavaScript (Node.js): guía completa con ejemplos
Flurl para C# (.NET): guía completa con ejemplos prácticos
Criptografía en C++: cifrado y hashes con OpenSSL y Crypto++