تسلسل الكائنات في TypeScript: المكتبات والطرق والأمثلة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

تسلسل الكائنات في TypeScript: دليل شامل

\n\n

التسلسل هو عملية تحويل كائن إلى تدفق من البايتات أو سلسلة نصية لنقلها عبر الشبكة أو تخزينها. في TypeScript، تتعقد هذه المهمة بسبب الحاجة إلى الحفاظ على الأنواع، ودعم تعدد الأشكال، والعمل مع الفئات. سنستعرض الأدوات والطرق الرئيسية.

\n\n

1. التسلسل المدمج: JSON.stringify / JSON.parse

\n\n

الآلية الأساسية في JavaScript/TypeScript هي الكائن العام JSON. يقوم بتسلسل الأنواع البسيطة فقط: السلاسل النصية، الأرقام، القيم المنطقية، المصفوفات والكائنات المسطحة. الطرق، الرموز، undefined، Date ونماذج الفئات - تُفقد.

\n\n
// مثال: تسلسل فئة\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// النتيجة: {"name":"Alice","createdAt":"2025-03-24T10:00:00.000Z"}\n// password لم يدخل في JSON (خاص)، لكن Date أصبح سلسلة نصية\n// عند إلغاء التسلسل سنحصل على كائن عادي، وليس نموذجاً من User\n\nconst parsed: User = JSON.parse(json) as User;\nconsole.log(parsed instanceof User); // false\n
\n\n

المشاكل:

\n
    \n
  • فقدان النوع (يتحول نموذج الفئة إلى object).
  • \n
  • لا يتم تسلسل الحقول الخاصة، الطرق، الدوال الجالبة (getters).
  • \n
  • التواريخ، Map، Set، BigInt تتطلب تحويلاً يدوياً.
  • \n
  • تعدد الأشكال غير مدعوم - يجب استعادة النوع يدوياً.
  • \n
\n\n

2. مكتبة class-transformer

\n\n

class-transformer هو الحل الأكثر شيوعاً لتسلسل/إلغاء تسلسل الفئات في TypeScript. تستخدم المُزينات (decorators) لوصف قواعد التحويل.

\n\n

التثبيت

\n
npm install class-transformer reflect-metadata
\n\n

مثال على الاستخدام

\n
import { 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) // تحويل متداخل\n  address!: Address;\n\n  @Expose()\n  @Transform(({ value }) => new Date(value)) // تحويل مخصص\n  hireDate!: Date;\n\n  // الطريقة لا تُسلسل\n  get displayName(): string {\n    return `${this.name} (ID: ${this.id})`;\n  }\n}\n\n// إلغاء التسلسل من كائن عادي\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// التسلسل مرة أخرى\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\n

المزايا:

\n
    \n
  • استعادة تلقائية للأنواع (الكائنات المتداخلة، المصفوفات).
  • \n
  • دعم تعدد الأشكال عبر @Type مع أداة تمييز (discriminator).
  • \n
  • تحويل القيم (التواريخ، الأرقام، التنسيقات المخصصة).
  • \n
  • العمل مع الحقول الخاصة عبر @Expose.
  • \n
\n\n

العيوب:

\n
    \n
  • الاعتماد على المُزينات (يتطلب experimentalDecorators في tsconfig).
  • \n
  • غير مناسب للأنظمة عالية التحميل (الانعكاس يبطئ الأداء).
  • \n
  • حجم الحزمة ~15KB (gzip).
  • \n
\n\n

3. Protocol Buffers مع protobuf-ts

\n\n

للهندسة المعمارية للخدمات الدقيقة و gRPC، غالباً ما يُستخدم Protocol Buffers. تنفيذ TypeScript protobuf-ts يولد أنواعاً مكتوبة

توصيات