Serialização de objetos em TypeScript: guia completo
\n\nSerialização é o processo de converter um objeto em um fluxo de bytes ou string para transmissão pela rede ou armazenamento. Em TypeScript, essa tarefa é complicada pela necessidade de preservar tipos, suportar polimorfismo e trabalhar com classes. Vamos analisar as principais ferramentas e abordagens.
\n\n1. Serialização nativa: JSON.stringify / JSON.parse
\n\nO mecanismo básico em JavaScript/TypeScript é o objeto global JSON. Ele serializa apenas tipos simples: strings, números, booleanos, arrays e objetos simples. Métodos, símbolos, undefined, Date e instâncias de classes são perdidos.
// Exemplo: serialização de classe\nclass User {\n constructor(\n public name: string,\n private password: string,\n public createdAt: Date = new Date()\n ) {}\n}\n\nconst user = new User('Alice', 'secret123');\nconst json = JSON.stringify(user);\n// Resultado: {"name":"Alice","createdAt":"2025-03-24T10:00:00.000Z"}\n// password não foi para o JSON (private), mas Date virou string\n// Na desserialização, obteremos um objeto comum, não uma instância de User\n\nconst parsed: User = JSON.parse(json) as User;\nconsole.log(parsed instanceof User); // false\n\n\nProblemas:
\n- \n
- Perda de tipo (instância de classe se transforma em
object). \n - Campos privados, métodos e getters não são serializados. \n
- Datas, Map, Set, BigInt exigem conversão manual. \n
- Polimorfismo não é suportado — é necessário restaurar o tipo manualmente. \n
2. Biblioteca class-transformer
\n\nclass-transformer é a solução mais popular para serialização/desserialização de classes em TypeScript. Ela usa decoradores para descrever regras de transformação.
\n\nInstalação
\nnpm install class-transformer reflect-metadata\n\nExemplo de uso
\nimport { plainToClass, classToPlain, Expose, Transform, Type } from 'class-transformer';\nimport 'reflect-metadata';\n\nclass Address {\n @Expose()\n city!: string;\n\n @Expose()\n street!: string;\n}\n\nclass Employee {\n @Expose()\n id!: number;\n\n @Expose()\n name!: string;\n\n @Expose()\n @Type(() => Address) // transformação aninhada\n address!: Address;\n\n @Expose()\n @Transform(({ value }) => new Date(value)) // transformação personalizada\n hireDate!: Date;\n\n // Método não é serializado\n get displayName(): string {\n return `${this.name} (ID: ${this.id})`;\n }\n}\n\n// Desserialização a partir de um objeto simples\nconst plainData = {\n id: 1,\n name: 'Bob',\n address: { city: 'Moscow', street: 'Tverskaya' },\n hireDate: '2024-01-15T00:00:00.000Z'\n};\n\nconst employee = plainToClass(Employee, plainData);\nconsole.log(employee instanceof Employee); // true\nconsole.log(employee.hireDate instanceof Date); // true\n\n// Serialização de volta\nconst plain = classToPlain(employee);\nconsole.log(plain); // { id: 1, name: 'Bob', address: { city: 'Moscow', street: 'Tverskaya' }, hireDate: '2024-01-15T00:00:00.000Z' }\n\n\nVantagens:
\n- \n
- Restauração automática de tipos (objetos aninhados, arrays). \n
- Suporte a polimorfismo via
@Typecom discriminador. \n - Transformação de valores (datas, números, formatos personalizados). \n
- Trabalho com campos privados através de
@Expose. \n
Desvantagens:
\n- \n
- Dependência de decoradores (requer
experimentalDecoratorsno tsconfig). \n - Não é adequado para sistemas de alta carga (reflexão reduz a performance). \n
- Tamanho do bundle ~15KB (gzip). \n
3. Protocol Buffers com protobuf-ts
\n\nPara arquitetura de microsserviços e gRPC, Protocol Buffers é frequentemente utilizado. A implementação em TypeScript protobuf-ts gera código tipado
Também na biblioteca
Programação Reativa em C# (.NET) — Observable, Rx.NET e LINQ
Bibliotecas WebSocket Rust: Tokio-tungstenite e async-tungstenite para tempo real
CameraX para Kotlin: guia completo com exemplos práticos