تحويل JSON إلى TypeScript

الصق عينة JSON، فتستنتج الأداة واجهات TypeScript التي تطابق بنيتها. تُحدَّد أنواع الحقول بناءً على القيم الملاحظة (string، number، boolean، Array<T>)، وتحصل الكائنات المتداخلة على واجهات مسماة خاصة بها، بينما تصبح الحقول الملاحظة على أنها null أو مفقودة اختيارية (?) أو قابلة لأن تكون null (| null) حسب النمط الذي تفضله.

كيفية تحويل JSON إلى TypeScript

  1. 1

    الصق JSON

    عينة واحدة تكفي، لكن تقديم عدة عينات يحسّن استنتاج قابلية القيمة لأن تكون null وأنواع الاتحاد.

  2. 2

    اختر نمط الإخراج

    `interface` (الافتراضي)، أو الاسم المستعار `type`، أو واجهة للقراءة فقط تكون فيها جميع الحقول موسومة بـ `readonly`.

  3. 3

    اختر استراتيجية الحقول الاختيارية

    اجعل الحقل `?` (قد يكون غائبًا) أو `| null` (موجود دائمًا، لكن قد يكون null).

  4. 4

    انسخ الأنواع

    الصقها في ملف `.ts` لتحصل على وصول مُحكم النوع إلى استجابة الـ API.

مثال

المدخل:

{ "id": 1, "name": "Alice", "age": null, "tags": ["admin", "user"], "address": { "city": "Madrid" } }

الناتج:

interface User {
  id: number;
  name: string;
  age: number | null;
  tags: string[];
  address: Address;
}

interface Address {
  city: string;
}

تعيين الأنواع

JSON TypeScript
سلسلة نصية string
عدد صحيح / عدد عشري number
قيمة منطقية boolean
null فقط null
null + T T | null (أو T?)
مصفوفة من T T[]
مصفوفة مختلطة (T1 | T2)[]
كائن واجهة متداخلة مسماة
مصفوفة فارغة unknown[] (لا يمكن استنتاجه)

الحقل الاختياري مقابل الحقل القابل لأن يكون null

  • foo?: string، قد يكون هذا الحقل غائبًا عن الكائن، ويُطبَّق فحص undefined.
  • foo: string | null، هذا الحقل موجود دائمًا، لكنه قد يكون null بشكل صريح.
  • foo?: string | null، قد يكون غائبًا أو null.

لا يحتوي JSON نفسه على undefined، لكن واجهات الـ API تختلف في طريقة الإشارة إلى غياب الحقل. طابِق دلالات الـ API الذي تستخدمه.

  • عادةً ما تحذف واجهات REST الحقول المفقودة -> ?:.
  • تُعيد GraphQL دائمًا كل حقل مطلوب -> | null.
  • تستخدم بعض حزم SDK كلا الأسلوبين في سياقات مختلفة.

أنواع الاتحاد مقابل الأنواع الحرفية

إذا رصدت الأداة الحقل النصي نفسه بمجموعة صغيرة من القيم عبر العينات ("status": "pending"، "active"، "archived")، فيمكنها إخراج اتحاد من الحرفيات النصية:

status: "pending" | "active" | "archived";

فعِّل خيار «استنتاج اتحادات الحرفيات النصية» إذا رغبت في ذلك.

الأخطاء الشائعة

  • الاستنتاج من عينة واحدة. يصبح كل حقل إلزاميًا، ولا يمكن رصد قابلية القيمة لأن تكون null. للحصول على أنواع أفضل، مرِّر من 5 إلى 10 عينات متنوعة.
  • المصفوفات الفارغة. لا تعطي "tags": [] أي معلومات عن النوع، فيُخرِج المولّد unknown[]. قدِّم عينة تحتوي على عنصر واحد على الأقل.
  • المصفوفات مختلطة الأنواع. تُنتج [1, "two", true] النوع (number | string | boolean)[]. غالبًا ما يعني ذلك أن على JSON أن يُعاد تصميمه بدلًا من تحديد نوعه.
  • المفاتيح النصية الرقمية. يظل JSON {"1": "a", "2": "b"} كائنًا في TypeScript (Record<string, string>)، وليس مصفوفة. ويتعامل المولّد مع ذلك بشكل صحيح.

الأسئلة الشائعة

طابِق الـ API الخاص بك. واجهات REST التي تحذف الحقول ذات القيمة null تناسبها ?:. أما GraphQL التي تُعيد دائمًا كل حقل محدَّد فتناسبها | null. عند الشك، يكون T | null بالصيغة الإلزامية أكثر صرامة ويلتقط مزيدًا من الأخطاء وقت التصريف.

نعم، إذا فعّلت الخيار وقدّمت عدة عينات. الحقل الذي يظهر فيه ما بين قيمتين و5 قيم نصية مختلفة عبر العينات يُخرَج على شكل اتحاد حرفي. وبتجاوز هذه العتبة يعود إلى string.

في معظم الحالات interface، فهو مفتوح للتوسعة وتُحسّنه TypeScript بشكل أفضل. أما الأسماء المستعارة type فمفيدة للاتحادات والتقاطعات والصفوف (tuples) والأنواع المُعيَّنة (mapped types). للأنواع المشتقة من JSON يعمل كلاهما، فاختر ما يتوافق مع عرف المشروع.

نعم. يصبح كل كائن متداخل واجهة مستقلة، وتُشتق أسماؤها من المفتاح (user.address -> Address). أما البنى العميقة جدًا أو المتكررة فيُستحسن معها استخدام JSON Schema ومولّد مخصص لتحويل schema إلى TS.

أدوات ذات صلة

الأداة متاحة بلغات أخرى