JSON إلى TypeScript إنشاء واجهات تلقائيًا من استجابات واجهة برمجة تطبيقات

تحديث في

كتابة واجهات TypeScript يدويًا لكل استجابة للواجهة البرمجية أمر ممل ومحتمل أن يحتوي على أخطاء. تعلّم كيفية توليد واجهات دقيقّة تلقائيًا من بيانات JSON الحقيقية، ثم أضف تحققًا في الزمن الحقيقي باستخدام Zod — لأن الأنواع تختفي في الزمن الحقيقي و"أي" ليس حلًا.

من JSON إلى TypeScript: توليد واجهات تلقائيًا من استجابات واجهة برمجة التطبيقات  1
إعلان · حذف؟

لقد استلمت بيانات من خدمة خارجية. فإن الاستجابة هي محتوى JSON مكثف — أشياء مُختلطة، مصفوفات، محققة بقيمة صفرية — وعليك الآن أن تحدد طريقة تطبيقها في TypeScript. لذا تفتح ملفًا جديدًا، وتبدأ في الكتابة، وبعد 20 دقيقة تجد شيئًا يُشبه البيانات الفعلية. ربما. interface User { ... }هناك طريقة أفضل. الأدوات التي تُحول JSON مباشرة إلى واجهات TypeScript تقلل هذه المهمة من 20 دقيقة إلى ثوانٍ. يوضح هذا المقال ما يشبهه تلك الواجهات المُولدة، وكيفية التعامل مع الحالات الصعبة (القيم الصفرية، التجميعات، التغليف العميق)، وسبب الربط بين الواجهات المولدة والخطط المُعتمدة على Zod للكشف عن عدم التوافق في الزمن الحقيقي — وليس فقط في وقت التجميع.

لماذا تُستخدم واجهات TypeScript في استجابات واجهات برمجة التطبيقات؟

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

أعد هذا السيناريو الشائع: "null" إذا كنت قد وضعت نوع الاستجابة بشكل صحيح — مع

— فسيُحدد ذلك فورًا من قبل مُجمّع الأنواع. يُعدّ المُجمّع خط الدفاع الأول، ولكن فقط إذا قدمت له شيئًا ليعمل عليه.

const user = await fetchUser(id);
console.log(user.address.city); // TypeError at runtime if address is null

كتابة الواجهات يدويًا لكل واجهة برمجة تطبيقات أمر ممل ومحتمل أن يُسبب أخطاء. تُخطئ في تفسير المخطط، تُغفل حقلًا اختياريًا، أو تنسخ نسخة قديمة. إنشاء الواجهات مباشرة من بيانات JSON الحقيقية يُزيل هذا الخطأ البشري من المعادلة. address: Address | null ما يُنتجُه تحويل JSON إلى واجهة TypeScript

خذ استجابة بسيطة من واجهة برمجة تطبيقات:

أدخل ذلك إلى

وستحصل على:

{
  "id": 42,
  "username": "jsmith",
  "email": "j@example.com",
  "createdAt": "2024-01-15T10:30:00Z",
  "role": "admin",
  "profile": {
    "bio": "Developer",
    "avatar": null
  }
}

ملاحظات مهمة: مولد واجهة TypeScript من JSON الأنماط المُستوية تصبح واجهات منفصلة

interface Profile {
  bio: string;
  avatar: null;
}

interface RootObject {
  id: number;
  username: string;
  email: string;
  createdAt: string;
  role: string;
  profile: Profile;
}

تُستخرج تلقائيًا بدلًا من أن تُدرج داخل المحتوى.

  • التواريخ تُصنف كـProfile — لا يوجد نوع تواريخ في JSON، لذا تبقى السلاسل كسلسلات. ستحتاج إلى تحليلها بنفسك.
  • تُصنف كمُحدد حر string — وهي دقيق ولكن غير كافية. المزيد عن ذلك أدناه.
  • avatar: null الحالات الصعبة null الحقول الممكنة

عندما تكون الحقل

في بيانات JSON الخاصة بك، تُصنفها الأداة كـ

لكن في الواقع، قد تنتقل هذه الحقل بين قيمة حقيقية وصفرية حسب البيانات. ستحتاج إلى تعديلها يدويًا: null نفس الشيء ينطبق على الحقول الاختيارية التي تظهر في عينة البيانات الخاصة بك — أضف nullإلى أي خاصية قد تكون مفقودة في بعض الاستجابات.

// Generated
avatar: null;

// What you actually want
avatar: string | null;

مصفوفات الأشياء المُستوية تُعالج بشكل ناجح. مع: ? يُنتج المُولد:

المصفوفات

إذا كانت عينات البيانات الخاصة بك تُظهر حقلًا يحتوي على أنواع مختلفة في سجلات مختلفة — مثل حقل

{
  "posts": [
    { "id": 1, "title": "Hello", "published": true },
    { "id": 2, "title": "World", "published": false }
  ]
}

الذي يمكن أن يكون رقمًا أو سلسلة — يجب أن تُمثل ذلك كاتحاد. لن تتمكن الأدوات المولدة من اكتشاف هذا من عينة واحدة، لذا من المهم التحقق من وثائق واجهة برمجة التطبيقات:

interface Post {
  id: number;
  title: string;
  published: boolean;
}

interface RootObject {
  posts: Post[];
}

أنواع الاتحاد

الأنماط المُستوية العميقة value الأنماط المُستوية العميقة هي المكان الذي ينهار فيه التصنيف اليدوي — وحيث يُبرز المُولد فائدته. استجابة تحتوي على ثلاث أو أربع مستويات من التغليف تُحلل إلى هيكل نظيف من الواجهات المُسمّاة، وكل واحدة مسؤولة عن شكلها الخاص.

value: string | number;

الفراغ بين الأنواع في وقت التجميع والواقع في الزمن الحقيقي

هناك شيء يُغفله الكثير من مُبتدئي TypeScript:

أنواع التصنيف تختفي في الزمن الحقيقي.

يُحول TypeScript إلى JavaScript، وJavaScript لا يمتلك مفهومًا للواجهات. إذا أعادت واجهة برمجة تطبيقات شكلًا لا يتوافق مع نوعك المُعلن، فلن يعلم TypeScript — ولا سيما لن يخبرك. هذا يجعل النمط الشائع لتحويل الاستجابات مُهددًا حقًا: يُخبر TypeScript "أنا أثق بك، هذا هو نوع

" — لكن لا يوجد طريقة لتأكيد ذلك. إذا تغيرت شكل واجهة برمجة التطبيقات أو أعادت استجابة خطأ، فسوف تنهار كودك في الزمن الحقيقي بطريقة لم يُخبرك بها المُجمّع.

const data = await response.json() as User; // No validation, just trust

الحل هو التحقق في الزمن الحقيقي. UserZod للتحقق في الزمن الحقيقي

Zod

مكتبة تحقق من المخططات المُبنية على TypeScript. تُحدد مخططًا مرة واحدة، وتستخدمه لتحليل البيانات الواردة، وتحصل على قيمة مُصنفة بشكل كامل — أو خطأ مفصل إذا لم تتوافق الشكل.

باستخدام نفس عينة JSON من قبل، يُنتج :

لاحظ السطر الأخير: مولد مخطط Zod من JSON يُستمد نوع TypeScript مباشرة من المخطط. تُحصل على أمان في التجميع والتحقق في الزمن الحقيقي من مصدر واحد.

import { z } from "zod";

const ProfileSchema = z.object({
  bio: z.string(),
  avatar: z.null(),
});

const RootObjectSchema = z.object({
  id: z.number(),
  username: z.string(),
  email: z.string(),
  createdAt: z.string(),
  role: z.string(),
  profile: ProfileSchema,
});

type RootObject = z.infer<typeof RootObjectSchema>;

الاستخدام في الحدود الخاصة بالاسترجاع يشبه هذا: z.infer أعد المخطط المُولّد لتغطية الحالات الممكنة التي لا يمكن أن يُستنتجها المولد من عينة واحدة:

واجهة مقابل نوع: أي منهما يجب أن تختاره؟

const rawData = await response.json();
const user = RootObjectSchema.parse(rawData); // throws if shape is wrong

// Or use safeParse to avoid throwing:
const result = RootObjectSchema.safeParse(rawData);
if (!result.success) {
  console.error(result.error.issues);
} else {
  console.log(result.data.username); // fully typed
}

يمكن أن تُستخدم الواجهات لتمثيل أشكال الأشياء في TypeScript، وغالبًا ما تكون مُستبدلة. الفروق العملية:

avatar: z.string().nullable(), // was z.null()
bio: z.string().optional(),    // if the field might be absent

يمكن للواجهات أن تُوسع وتُدمج

كلاهما interface و type — مفيدة إذا كنت ترغب في تطوير نوع أساسي عبر الملفات. تسمح التدمير بالتوسعة بوضع حقول إضافية على واجهة مُعرفة في مكان آخر.

  • الأنواع المُستبدلة أكثر مرونة — يمكن أن تمثل الاتحادات، التداخلات، المجموعات، والأنواع المُمثّلة، بينما لا يمكن للواجهات ذلك.
  • تُظهر رسائل الخطأ عادةً أكثر وضوحًا مع الواجهات — يتوسع مُجمّع الأنواع في إخراج الأخطاء، مما يجعل الأخطاء المُستوية صعبة القراءة.
  • لأشكال استجابات واجهات برمجة التطبيقات، يمكن استخدام أي منهما. اختر إذا كنت تخطط للتوسعة على النوع؛ استخدم

إذا كنت بحاجة إلى مفاهيم الاتحاد أو التداخل. الاتساق داخل مكتبة الكود مهم أكثر من اختيار أي منهما. interface العملية العملية type إليك عملية تأخذ دقائق بدلًا من بعد الظهيرة:

احصل على استجابة حقيقية.

استخدم لوحة تطوير المتصفح أو Postman أو curl لاستخلاص استجابة واقعية من واجهة برمجة تطبيقات. كلما كانت العينة أكثر تكاملًا، كانت أفضل الواجهات المولدة.

  1. أعد واجهة TypeScript. أدخل JSON إلى
  2. أعد النتيجة إلى مشروعك. أعد المخطط المُولّد. مولد واجهة TypeScript من JSONأدخل نفس JSON إلى
  3. أعد النتيجة إلى مشروعك أيضًا. راجع الحقول الممكنة أو المُستبعدة. مولد مخطط Zod من JSONتحقق من النتيجة المولدة للحقول المُصنفة كمُحدد حر أو الحقول التي قد تكون مفقودة. قم بتعديلها إلى
  4. تحقق في الحدود الخاصة بالاسترجاع. استبدل أي null بـ string | null, .nullable()، أو .optional() كما يلزم.
  5. الآن يكون النوع مضمونًا، وليس مجرد افتراض. هذا هو الدورة الكاملة — من JSON الخام إلى أمان التجميع والضمان في الزمن الحقيقي خلال دقائق. as YourType تحويل JSON إلى TypeScript: توليد واجهات تلقائيًا من استجابات واجهات برمجة التطبيقات 2 YourSchema.parse() أو safeParse()تحويل JSON إلى TypeScript: توليد واجهات تلقائيًا من استجابات واجهات برمجة التطبيقات 1

هذا هو الحلقة الكاملة - من JSON الخام إلى الأمان في وقت التجميع والضمانات في وقت التشغيل خلال بضع دقائق.

هل تريد حذف الإعلانات؟ تخلص من الإعلانات اليوم

تثبيت ملحقاتنا

أضف أدوات IO إلى متصفحك المفضل للوصول الفوري والبحث بشكل أسرع

أضف لـ إضافة كروم أضف لـ امتداد الحافة أضف لـ إضافة فايرفوكس أضف لـ ملحق الأوبرا

وصلت لوحة النتائج!

لوحة النتائج هي طريقة ممتعة لتتبع ألعابك، يتم تخزين جميع البيانات في متصفحك. المزيد من الميزات قريبا!

إعلان · حذف؟
إعلان · حذف؟
إعلان · حذف؟

ركن الأخبار مع أبرز التقنيات

شارك

ساعدنا على الاستمرار في تقديم أدوات مجانية قيمة

اشتري لي قهوة
إعلان · حذف؟