Kodokon kodokon.com

توصيف الشيفرة الواقعية: DOM وfetch وJSON

حافظ على أنواع موثوقة عند حدود تطبيقك، حيث يفلت الـ DOM والشبكة وJSON من رقابة المترجم.

10 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

تبدأ الشيفرة الواقعية حيث تنتهي الأنواع المثالية: الـ DOM والشبكة وJSON تعيد بيانات لا يستطيع TypeScript تخمينها. الحدّ الأول: الـ DOM. تعيد querySelector النوع Element | null، وهو نوع أكثر غموضًا من أن يقرأ value أو يستدعي focus().

TYPESCRIPT
const input = document.querySelector<HTMLInputElement>(
  "#email"
);

if (input) {
  input.value = "test@example.com";
  input.focus();
}
معامل نوع على querySelector وحارس ضد null

معامل النوع وعدٌ تقطعه للمترجم: أنت المسؤول عن استهداف المُحدِّد (selector) الصحيح. وحين يأتي العنصر من حدث، فضّل فحص instanceof، الذي يتحقق من النوع فعليًا أثناء التشغيل.

TYPESCRIPT
const form = document.querySelector("form");

form?.addEventListener("submit", (event) => {
  event.preventDefault();
  if (event.target instanceof HTMLFormElement) {
    console.log(new FormData(event.target));
  }
});
instanceof يتحقق من النوع ويضيّقه في آنٍ واحد

الحدّ الثاني: الشبكة. تعيد response.json() النوع Promise<any>، أي بابًا مفتوحًا على أي شيء. الحد الأدنى المهني: صرّح عن النوع المتوقع، تحقق من response.ok، ومركِز الاستدعاء في دالة موصَّفة النوع.

TYPESCRIPT
interface Post {
  id: number;
  title: string;
}

async function getPost(id: number): Promise<Post> {
  const url = `https://api.example.com/posts/${id}`;
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }
  return (await response.json()) as Post;
}
استدعاء fetch مركَّز وموصَّف النوع

تبقى as Post مجرد إعلان ثقة: إذا تغيّرت واجهة API، فلن ينبّهك شيء أثناء التشغيل. أما البيانات الحرجة فاكتب لها حارس نوع يتحقق من الشكل الفعلي لـ JSON قبل استخدامه.

TYPESCRIPT
function isPost(value: unknown): value is Post {
  if (typeof value !== "object" || value === null) {
    return false;
  }
  const obj = value as Record<string, unknown>;
  return (
    typeof obj.id === "number" &&
    typeof obj.title === "string"
  );
}
حارس نوع يتحقق من JSON المستلَم (متابعةً للمثال)

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. ما نوع القيمة المُعادة من response.json() على استجابة fetch؟
    • Promise<unknown>
    • Promise<any>
    • Promise<object>
    • any
  2. لماذا نفضّل event.target instanceof HTMLFormElement على توكيد as HTMLFormElement؟
    • لأنه أسرع أثناء التشغيل
    • لأن instanceof يتحقق فعليًا من النوع أثناء التشغيل، بينما as تكتفي بإسكات المترجم
    • لأن as ممنوعة في الوضع الصارم
  3. ماذا تعيد document.querySelector('#email') دون معامل نوع؟
    • HTMLInputElement
    • Element | null
    • HTMLElement
    • null