مقدمة في العمل مع JSON في TypeScript
JSON (JavaScript Object Notation) لا يزال واحداً من أكثر التنسيقات شيوعاً لتبادل البيانات بين العميل والخادم. في TypeScript، الذي يُعد امتداداً مقيداً بالأنواع فوق JavaScript، يتطلب العمل مع JSON اهتماماً خاصاً بأنواع البيانات. في هذه المقالة، سنشرح بالتفصيل كيفية تحليل (parsing) وتسلسل (serializing) JSON بشكل صحيح في TypeScript، مع تجنب الأخطاء النمطية والاستفادة من مزايا التقييد الثابت للأنواع.
يوفر TypeScript جميع الطرق المضمنة في JavaScript للعمل مع JSON، ولكنه يضيف إليها نظاماً قوياً للأنواع. وهذا يسمح بإنشاء كود أكثر موثوقية وقابلية للتنبؤ. سنستعرض العمليات الأساسية والتقنيات المتقدمة، بما في ذلك دوال التحقق المخصصة والعمل مع الأدوية (Generics).
أساسيات تحليل JSON: JSON.parse()
تقوم طريقة JSON.parse() بتحويل سلسلة JSON إلى كائن JavaScript. في TypeScript، من المهم تحديد نوع النتيجة بشكل صحيح حتى يتمكن المترجم من التحقق من صحة الوصول إلى خصائص الكائن.
الصيغة الأساسية وتحديد النوع
لننظر إلى مثال بسيط:
const jsonString = '{"name": "Анна", "age": 30, "city": "Москва"}';const user = JSON.parse(jsonString);console.log(user.name); // Аннаالمشكلة هي أن TypeScript لا يعرف بنية الكائن user. المتغير له النوع any، مما يحرمنا من جميع مزايا التقييد. الحل الصحيح هو تحديد النوع بشكل صريح:
interface User { name: string; age: number; city: string;}
const jsonString = '{"name": "Анна", "age": 30, "city": "Москва"}';const user: User = JSON.parse(jsonString); // خطأ!// Type 'any' is not assignable to type 'User'.سيصدر TypeScript خطأً لأن JSON.parse() تُرجع any، ونحن نحاول تعيينها لمتغير مقيد النوع. استخدم تحويل النوع (Type Casting):
const user = JSON.parse(jsonString) as User;console.log(user.name.toUpperCase()); // АННАتحليل آمن مع التحقق من الأنواع
تحويل النوع باستخدام as هو حل سريع، لكنه لا يضمن أن البيانات تتطابق فعلياً مع البنية المتوقعة. بالنسبة لكود الإنتاج، يُوصى بإنشاء دوال تحقق:
function parseUser(data: string): User | null { try { const parsed = JSON.parse(data); if (typeof parsed === 'object' && parsed !== null && typeof parsed.name === 'string' && typeof parsed.age === 'number' && typeof parsed.city === 'string') { return parsed as User; } return null; } catch { return null; }}
const user = parseUser('{"name": "Иван", "age": 25, "city": "СПб"}');if (user) { console.log(`المستخدم: ${user.name}, العمر: ${user.age}`);}يمنع هذا النهج أخطاء وقت التشغيل إذا أعاد الخادم بيانات غير صحيحة.
التسلسل: JSON.stringify()
تقوم طريقة JSON.stringify() بتحويل كائن JavaScript إلى سلسلة JSON. في TypeScript، تعمل هذه الطريقة كما في JavaScript، ولكن مع مراعاة الأنواع.
تسلسل بسيط
const user: User = { name: 'Мария', age: 28, city: 'Казань'};
const jsonString = JSON.stringify(user);console.log(jsonString); // {"name":"Мария","age":28,"city":"Казань"}معلمات التنسيق
للحصول على مخرجات قابلة للقراءة، استخدم المعاملين replacer و space:
const user = { name: 'Алексей', age: 35, city: 'Новосибирск', password: 'secret123'};
// استبعاد حقل passwordconst jsonString = JSON.stringify(user, ['name', 'age', 'city'], 2);console.log(jsonString);/* الإخراج:{ "name": "Алексей", "age": 35, "city": "Новосибирск"}*/المعامل repla