0Pricing
TypeScript Academy · درس

المنشئات ذات الكتابة القوية

صمّم منشئات قابلة للتسلسل تراكم الخيارات ذات الأنواع، واضمن الخطوات المطلوبة والتركيبات الصحيحة باستخدام الأنواع العامة والأنواع الشرطية.

المنشئات ذات الكتابة القوية درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 3 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 3 دروس في المجموع.

مقدمة

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

  • تجميع الخيارات في نوع عام
  • تقييد الخطوات باستخدام العلامات
  • الحفاظ على بساطة تجربة المطوّر

علامات الحالة

تُرجع كل خطوة نوعًا جديدًا من الحالة؛ ولا يصبح build متاحًا إلا عندما تكون العلامات المطلوبة true.

type Flags = { method: boolean; url: boolean }

type With<F extends Partial<Flags>> = { flags: F }

type True = true

type Builder<F extends Partial<Flags>, O extends Record<string, unknown>> = With<F> & {
  method<M extends "GET" | "POST">(m: M): Builder<F & { method: True }, O & { method: M }>
  url<U extends `/${string}`>(u: U): Builder<F & { url: True }, O & { url: U }>
  build(this: Builder<{ method: True; url: True }, any>): O
}

function createBuilder(): Builder<{}, {}> {
  return {
    flags: {},
    method(m) { return { ...this, flags: { ...this.flags, method: true }, method: this.method, url: this.url, build: this.build } as any },
    url(u) { return { ...this, flags: { ...this.flags, url: true }, method: this.method, url: this.url, build: this.build } as any },
    build() { return this as any }
  } as any
}

const b = createBuilder()
const good = b.method("GET").url("/users").build()   // ok
// const bad = b.build() // error: build requires method & url flags

تجميع الخيارات

اجمعوا الخيارات في النوع العام O؛ إذ تُرجع كل استدعاءات نوعًا يضيف خصائص جديدة.

type B2<F extends Partial<Flags>, O extends Record<string, unknown>> = With<F> & {
  header<K extends string, V extends string>(k: K, v: V): B2<F, O & { headers: Record<K, V> }>
  query<K extends string, V extends string>(k: K, v: V): B2<F, O & { query: Record<K, V> }>
  method<M extends "GET" | "POST">(m: M): B2<F & { method: True }, O & { method: M }>
  url<U extends `/${string}`>(u: U): B2<F & { url: True }, O & { url: U }>
  build(this: B2<{ method: True; url: True }, any>): O
}

function builder2(): B2<{}, {}> { return {} as any }

const conf = builder2()
  .method("POST")
  .url("/login")
  .header("x-id", "42")
  .query("next", "home")
  .build()

التركيبات الصالحة

قيّدوا التركيبات باستخدام الأنواع الشرطية: اجعلوا body متاحًا فقط عند استخدام POST.

type Method = "GET" | "POST"

type BodyIfPost<M extends Method, B> = M extends "POST" ? { body: B } : {}

type B3<F extends Partial<Flags>, O extends Record<string, unknown>> = With<F> & {
  method<M extends Method>(m: M): B3<F & { method: True }, O & { method: M }>
  url<U extends `/${string}`>(u: U): B3<F & { url: True }, O & { url: U }>
  body<B>(b: B & (O extends { method: "POST" } ? unknown : never)): B3<F, O & BodyIfPost<O extends { method: infer M } ? Extract<M, Method> : Method, B>>
  build(this: B3<{ method: True; url: True }, any>): O
}

function builder3(): B3<{}, {}> { return {} as any }

const ok = builder3().method("POST").url("/u").body({ a: 1 }).build()
// const badBody = builder3().method("GET").url("/u").body({ a: 1 }).build() // compile-time error

خط أنابيب متغير الطول

اجمعوا الخطوات في مجموعة باستخدام مصفوفة tuple متغيرة الطول؛ وأديروا المدخلات والمخرجات باستخدام Parameters/ReturnType.

type Step<A extends any[], R> = (...args: A) => R

type Pipeline<P extends Step<any, any>[]> = {
  use<S extends Step<any, any>>(...s: [S]): Pipeline<[...P, S]>
  run<A extends Parameters<P[0]>>(this: Pipeline<P>, ...args: A): ReturnType<P[number]>
}

function pipeMake(): Pipeline<[]> { return {} as any }

const pipe = pipeMake()
  .use((a: string) => a.length)
  .use((n: number) => n % 2 === 0)
// pipe.run("abc") // demo; implementation omitted

نصائح

نصائح:

احتفظوا بالحالة كنوع عام وهمي؛ ولا تثقلوا وقت التشغيل.

أبقوا أسماء الخطوات قصيرة وثابتة (method وurl).

افصلوا التركيبات الصعبة باستخدام الأنواع الشرطية؛ وحافظوا على نظافة السلسلة.

التحقق من تقييد Builder

تحقق سريع: كيف نضمن استدعاء .method() قبل .build()؟

مراجعة

مراجعة: انقلوا الحالة ذات النوع عبر السلسلة، واجمعوا الخيارات في الأنواع العامة، واكتشفوا التسلسلات غير الصالحة أثناء الترجمة.

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

هل درس «المنشئات ذات الكتابة القوية» مجاني؟

نعم — نص درس «المنشئات ذات الكتابة القوية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 3 دروس في المجموع.

ماذا ستتعلم في «المنشئات ذات الكتابة القوية»؟

صمّم منشئات قابلة للتسلسل تراكم الخيارات ذات الأنواع، واضمن الخطوات المطلوبة والتركيبات الصحيحة باستخدام الأنواع العامة والأنواع الشرطية. تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟

لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 3.

كم من الوقت يستغرق درس «المنشئات ذات الكتابة القوية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟

نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. عناصر rest في المجموعات وأنواع curry
  2. تركيب الدوال والمعاملات بأمان
  3. المنشئات ذات الكتابة القوية
← العودة إلى TypeScript Academy