مقدمة: لماذا JSON و TypeScript هما الثنائي المثالي
\nفي تطوير الويب الحديث، أصبح JSON (JavaScript Object Notation) تنسيقًا عالميًا لتبادل البيانات بين العميل والخادم، وتخزين التهيئات، ونقل المعلومات في واجهات API. TypeScript، كإضافة فوق JavaScript، يضيف إلى هذه المرونة نظامًا قويًا للأنواع، مما يجعل العمل مع JSON ليس فقط مريحًا، بل وآمنًا أيضًا. في هذه المقالة، سنشرح كيفية تحليل (تحويل سلسلة JSON إلى كائن) وتسلسل (تحويل كائن إلى سلسلة JSON) البيانات بشكل صحيح باستخدام TypeScript. المادة موجهة للمطورين المبتدئين الذين هم على دراية بأساسيات TypeScript، لكنهم يريدون العمل بثقة مع JSON.
\n\nما الذي ستتعلمه
\n- \n
- كيفية استخدام الطرق المضمنة
JSON.parse()وJSON.stringify(). \n - كيفية كتابة أنواع البيانات أثناء التحليل لمنع الأخطاء. \n
- كيفية معالجة الاستثناءات والتحقق من صحة JSON. \n
- أمثلة عملية مع سيناريوهات حقيقية. \n
1. الأساسيات: طريقتي JSON.parse() و JSON.stringify()
\nيرث TypeScript من JavaScript طريقتين عالميتين للعمل مع JSON. وهما متاحتان دون الحاجة لاستيراد مكتبات إضافية.
\n\n1.1. تحليل JSON إلى كائن: JSON.parse()
\nالطريقة JSON.parse() تأخذ سلسلة نصية بتنسيق JSON وتعيد كائن JavaScript (أو مصفوفة، رقم، سلسلة). في TypeScript، يمكننا تحديد النوع المتوقع للنتيجة باستخدام الأدوية (Generics).
// مثال بسيط بدون كتابة أنواع\nconst jsonString = '{"name": "أليس", "age": 30}';\nconst user = JSON.parse(jsonString);\nconsole.log(user.name); // "أليس"\n\n1.2. تسلسل كائن إلى JSON: JSON.stringify()
\nالطريقة JSON.stringify() تحول كائنًا أو قيمة JavaScript إلى سلسلة JSON. وهي تعالج تلقائيًا جميع الأنواع البدائية والمصفوفات والكائنات البسيطة.
const user = {\n name: "بوب",\n age: 25,\n isAdmin: false\n};\nconst jsonString = JSON.stringify(user);\nconsole.log(jsonString); // '{"name":"بوب","age":25,"isAdmin":false}'\n\n2. كتابة أنواع البيانات عند تحليل JSON في TypeScript
\nالميزة الرئيسية لـ TypeScript هي إمكانية تحديد نوع نتيجة التحليل. هذا يحمي الكود من الأخطاء أثناء وقت الترجمة ويجعله موثقًا ذاتيًا.
\n\n2.1. استخدام الواجهات والأدوية (Generics)
\nأنشئ واجهة تصف هيكل بياناتك، وقم بتمريرها إلى JSON.parse() كأداة (Generic):
interface User {\n id: number;\n name: string;\n email: string;\n isActive: boolean;\n}\n\nconst jsonData = '{"id": 1, "name": "فيكتور", "email": "victor@example.com", "isActive": true}';\nconst user: User = JSON.parse(jsonData);\nconsole.log(user.email); // "victor@example.com"\n// user.id الآن هو number بشكل صارم\n\n2.2. معالجة الكائنات المتداخلة والمصفوفات
\nتعمل الواجهات بشكل ممتاز مع الهياكل المعقدة:
\ninterface Address {\n city: string;\n zip: string;\n}\n\ninterface Employee {\n id: number;\n name: string;\n address: Address;\n skills: string[];\n}\n\nconst employeeJson = '{"id": 101, "name": "إيلينا", "address": {"city": "موسكو", "zip": "101000"}, "skills": ["TS", "JS", "Python"]}';\nconst employee: Employee = JSON.parse(employeeJson);\nconsole.log(employee.address.city); // "موسكو"\n\n2.3. ماذا يحدث إذا لم يتطابق النوع؟
\nمن المهم أن تفهم: TypeScript يتحقق من الأنواع فقط في مرحلة الترجمة. إذا جاء في وقت التشغيل JSON بهيكل مختلف (على سبيل المثال، age سيكون سلسلة نصية بدلاً من رقم)، سيحدث الخطأ في الكود، ولكن ليس في JSON.parse(). للسلامة الكاملة، استخدم أدوات التحقق من الصحة في وقت التشغيل (مثل Zod أو io-ts)، ولكن بالنسبة لمعظم المشاريع التعليمية، تكفي الواجهات.
3. التسلسل: التفاصيل الدقيقة والتحويلات المخصصة
\nيمكن أيضًا تخصيص الطريقة JSON.stringify()