Сериализация объектов в TypeScript: библиотеки, методы и примеры

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Сериализация объектов в TypeScript: полное руководство

Сериализация — процесс преобразования объекта в поток байтов или строку для передачи по сети или сохранения. В TypeScript эта задача усложняется необходимостью сохранять типы, поддерживать полиморфизм и работать с классами. Рассмотрим основные инструменты и подходы.

1. Встроенная сериализация: JSON.stringify / JSON.parse

Базовый механизм в JavaScript/TypeScript — глобальный объект JSON. Он сериализует только простые типы: строки, числа, булевы значения, массивы и плоские объекты. Методы, символы, undefined, Date и экземпляры классов — теряются.

// Пример: сериализация класса
class User {
  constructor(
    public name: string,
    private password: string,
    public createdAt: Date = new Date()
  ) {}
}

const user = new User('Alice', 'secret123');
const json = JSON.stringify(user);
// Результат: {"name":"Alice","createdAt":"2025-03-24T10:00:00.000Z"}
// password не попал в JSON (private), но Date стал строкой
// При десериализации мы получим обычный объект, не экземпляр User

const parsed: User = JSON.parse(json) as User;
console.log(parsed instanceof User); // false

Проблемы:

  • Потеря типа (экземпляр класса превращается в object).
  • Не сериализуются приватные поля, методы, геттеры.
  • Даты, Map, Set, BigInt требуют ручного преобразования.
  • Полиморфизм не поддерживается — нужно вручную восстанавливать тип.

2. Библиотека class-transformer

class-transformer — наиболее популярное решение для сериализации/десериализации классов в TypeScript. Она использует декораторы для описания правил преобразования.

Установка

npm install class-transformer reflect-metadata

Пример использования

import { plainToClass, classToPlain, Expose, Transform, Type } from 'class-transformer';
import 'reflect-metadata';

class Address {
  @Expose()
  city!: string;

  @Expose()
  street!: string;
}

class Employee {
  @Expose()
  id!: number;

  @Expose()
  name!: string;

  @Expose()
  @Type(() => Address) // вложенная трансформация
  address!: Address;

  @Expose()
  @Transform(({ value }) => new Date(value)) // кастомное преобразование
  hireDate!: Date;

  // Метод не сериализуется
  get displayName(): string {
    return `${this.name} (ID: ${this.id})`;
  }
}

// Десериализация из plain object
const plainData = {
  id: 1,
  name: 'Bob',
  address: { city: 'Moscow', street: 'Tverskaya' },
  hireDate: '2024-01-15T00:00:00.000Z'
};

const employee = plainToClass(Employee, plainData);
console.log(employee instanceof Employee);          // true
console.log(employee.hireDate instanceof Date);     // true

// Сериализация обратно
const plain = classToPlain(employee);
console.log(plain); // { id: 1, name: 'Bob', address: { city: 'Moscow', street: 'Tverskaya' }, hireDate: '2024-01-15T00:00:00.000Z' }

Преимущества:

  • Автоматическое восстановление типов (вложенные объекты, массивы).
  • Поддержка полиморфизма через @Type с дискриминатором.
  • Трансформация значений (даты, числа, кастомные форматы).
  • Работа с приватными полями через @Expose.

Недостатки:

  • Зависимость от декораторов (требуется experimentalDecorators в tsconfig).
  • Не подходит для высоконагруженных систем (рефлексия замедляет работу).
  • Размер бандла ~15KB (gzip).

3. Протокол буферы (Protocol Buffers) с protobuf-ts

Для микросервисной архитектуры и gRPC часто используют Protocol Buffers. TypeScript-реализация protobuf-ts генерирует типизированный код из .proto файлов.

Пример .proto файла

syntax = "proto3";

message UserProto {
  int32 id = 1;
  string name = 2;
  string email = 3;
  google.protobuf.Timestamp created_at = 4;
}

Использование в TypeScript

import { UserProto } from './generated/user';
import { Timestamp } from './generated/google/protobuf/timestamp';

const user = User                    

Рекомендаций