§

عينة JSON

جارٍ تحضير مُستنتِج الأنواع…
§

واجهات TypeScript

TypeScript

فرق TypeScript الأمريكية تصطدم بهذه المشكلة مبكراً. تشحن SDKs الكبرى عملاء مُصنَّفين (Stripe وTwilio وAWS)، لكن الخدمات الداخلية وحمولات webhook التابعين نادراً ما تفعل، فسير العمل النموذجي هو: التقاط استجابة حقيقية في لوحة الشبكة، ولصقها هنا، وتسمية الجذر بعد نقطة النهاية، ونسخ الناتج في مجلد types الخاص بالمشروع. من هناك، يلتقط الوضع الصارم التناقضات التي نسيتها الوثائق. المُستنتِج يعمل بالكامل في متصفحك، فحمولات واجهات API للتدريج والأجسام الموقّعة للـ webhook ونقاط النهاية غير المُصدَرة لا تصل أبداً إلى خدمة مستضافة.

كيف يعمل استنتاج JSON إلى TypeScript؟

الاستنتاج هو مرور واحد على شجرة JSON المُحللة. تقرأ الأداة كل قيمة وتختار لها نوع TypeScript، ثم تكتب واجهةً واحدة لكل كائن وجدته.

  1. تحليل عينة JSON بالمحلل الأصلي في المتصفح ورفض المدخلات المشوّهة مع تلميح سطر/عمود.
  2. استشمام نوع TypeScript لكل قيمة — string أو number أو boolean أو null أو مصفوفة أو كائن متداخل.
  3. إعطاء كل كائن متداخل اسم واجهة مشتق من مفتاح الخاصية الأب (فـ user.address تصبح واجهة Address).
  4. دمج أنواع العناصر عبر كل مصفوفة كي تُنتج قائمة من {id: 1} و{id: 2, label: "x"} اتحاداً بالحقول الاختيارية الصحيحة.
  5. تطبيق خياراتك (interface أو type، وreadonly، والاختياري-القابل للإلغاء) وإصدار التصريحات بترتيب الاعتماد كي يُصرَّف الملف بدون إشارات مسبقة.

لماذا تولِّد أنواع TypeScript من JSON؟

  • معظم أخطاء الشكل قابلة للاكتشاف في وقت الترصيف إذا كان نوع الاستجابة مكتوباً. استنتاج واجهة من حمولة حقيقية يكتب معظمها لك، والوضع الصارم يلتقط الحقل الذي نسيته الوثائق.
  • إقران الواجهات المُستنتَجة مع مُدقِّق وقت التشغيل كـ Zod أو io-ts يمنح الشكل ذاته وظيفتين: إكمال تلقائي للمحرر في التطوير و400 على الحافة حين يُرسل الإنتاج شيئاً غير متوقع.
  • خادم لغة TypeScript يُظهر فقط الحقول التي يعرفها. بمجرد استيراد الواجهة المُستنتَجة، يعمل الإكمال التلقائي في اللحظة التي تكتب فيها النقطة — لا مزيد من cast as any على الاستجابة والبحث المحبط في المستودع.
  • إذا كنت على وشك كتابة مواصفة OpenAPI، فالواجهة المُستنتَجة هي مسودة أولى سريعة لمخطط الاستجابة. ستحتاج إلى أمثلة وقيود مكتوبة يدوياً، لكن أسماء الخصائص والأنواع صحيحة بالفعل.

التطبيقات الشائعة

الاستنتاج يُفيد أكثر حين توجد حمولة حقيقية لكن لا يوجد مخطط.

  • كتابة أنواع حمولات webhook التابعين من Stripe وGitHub وTwilio قبل كتابة مُعالِج.
  • بذر الأنواع لواجهة REST API داخلية كي يبدأ فريق الواجهة الأمامية البرمجة مقابلها في اليوم ذاته الذي تُطلَق فيه الواجهة الخلفية.
  • توليد نقطة بداية لمخطط Zod أو io-ts أو Valibot من استجابة API مُلاحَظة.

كيف يبدو الناتج؟

لمستند JSON عينة واسم جذر، يُنتج المولِّد شجرة واجهات، واحدة لكل كائن متداخل. للمدخل أدناه باسم الجذر User:

الصق {"id":1,"name":"Alice","tags":["a","b"],"address":{"city":"Paris"}} باسم الجذر User ويولِّد المولِّد:

export interface User {
  id: number;
  name: string;
  tags: string[];
  address: Address;
}

export interface Address {
  city: string;
}
lاحظ أن address رُقِّيَت إلى واجهتها المُسمَّاة — هذا هو الناتج المرتَّب بحسب الاعتماد. نفس JSON بأسلوب تصريح type بدلاً من interface سيُصدر export type User = {...}؛ ومع تفعيل مفتاح readonly، كل خاصية تحصل على مُعدِّل readonly.

خيارات المولِّد

أسلوب التصريح

اختر interface (التعبير الاصطلاحي القياسي في TypeScript لأشكال الكائنات) أو type (مفيد إذا ستحتاج لاحقاً إلى أنواع مخصّصة أو أنواع شرطية أو تقاطعات). كلاهما يُنتج سلوكاً مطابقاً في وقت التشغيل؛ الاختيار تفضيل في أسلوب الكتابة.

الحقول الاختيارية القابلة للإلغاء

حين تكون قيمة العينة null، يصبح نوع الحقل T | null. تفعيل هذا الخيار يُضيف أيضاً مُعدِّل ? كي يكون الحقل اختيارياً من الجانب TypeScript — مفيد حين تحذف الواجهة المفتاح كلياً أحياناً بدلاً من إرجاع null.

مُعدِّل Readonly

يُضيف readonly أمام كل تصريح خاصية كي تُطابق الواجهة المُصدَرة نموذج بيانات غير قابل للتغيير. مفيد لشرائح حالة Redux واستجابات API المجمّدة أو أي مكان تريد فيه من المُصرِّف تعليم الطفرة العرضية.

هل يدعم الكائنات المتداخلة والمصفوفات؟

نعم. كل كائن متداخل يصبح واجهةً مُسمَّاة مشتقة من مفتاح الخاصية الأب، والمصفوفات تستنتج نوع العنصر من محتوياتها. مصفوفات الكائنات تحصل على واجهة لكل شكل كائن مع أنواع اتحاد حيث تتباين الأشكال.

كيف تُستنتَج الحقول الاختيارية؟

شغِّل مفتاح "وسِّم الحقول القابلة للإلغاء اختيارية" وأي حقل قيمته المأخوذة كعينة null يحصل على مُعدِّل ? على المفتاح بالإضافة إلى | null في النوع. بدون المفتاح، يظل الحقل مطلوباً والنوع مجرد T | null.

هل يدعم اتحادات المُميَّز؟

تظهر أنواع الاتحاد الأساسية حين تحمل مصفوفة عناصر ذات أشكال مختلطة أو حين يحمل حقل قيمةً وnull معاً. الاستنتاج الكامل للاتحاد المُميَّز (اختيار type أو kind كعلامة وتقسيم المتغايرات) يحتاج عينات متعددة — هذا مخطط لكنه ليس في البناء الحالي.

هل يمكنني استنتاج الأنواع من عينات JSON متعددة؟

ليس بعد — المُستنتِج اليوم يقرأ عينة واحدة في كل مرة. إذا كانت لديك حمولتان يجب أن تتشاركا واجهةً (مثل نقطة نهاية قائمة ونقطة نهاية عنصر واحد)، الحل العملي هو دمجهما في مصفوفة واحدة، والتوليد من ذلك، ثم إعادة تسمية أنواع الاتحاد الناتجة. استنتاج متعدد العينات مخطط لأنه الطريقة الوحيدة لاكتشاف الحقول الموجودة في استجابة وغائبة في أخرى.

الصق حمولة، وسمِّ الجذر، وانسخ الواجهات. خط الأنابيب كاملاً يعمل في متصفحك، فواجهة API غير مُصدَرة أو جسم webhook موقَّع يبقى على جهازك.