0Pricing
TypeScript Academy · درس

المكوّنات متعددة الأشكال؛ خصائص as

أنشئ مكوّن Button متعدد الأشكال باستخدام خاصية as، وادمج خصائص DOM الأصلية، وحدد أنواع المراجع باستخدام forwardRef و ComponentRef .

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

مقدمة

الهدف: إنشاء زر متعدد الأشكال واحد يمكن عرضه كـ button أو a أو أي عنصر عبر الخاصية as، مع الحفاظ على أنواع الخصائص والمراجع.

  • تقييد T إلى React.ElementType
  • دمج الخصائص بأمان
  • تحديد نوع المرجع المُمرَّر

الأنواع الأساسية

ابدأ بـ OwnProps وبالأداة المساعدة PolymorphicProps<T, P> التي تدمج الخصائص الأصلية لـ T مع خصائصك.

import React from "react"

type OwnProps = {
  variant?: "solid" | "outline"
  children: React.ReactNode
}

type PolymorphicProps<T extends React.ElementType, P> = {
  as?: T
} & P & Omit<React.ComponentPropsWithoutRef<T>, keyof P | "as">

// Example: Omit avoids prop collisions (e.g., our OwnProps vs intrinsic props)

الزر متعدد الأشكال

يستخدم المكوّن button افتراضيًا، لكنه يقبل as. ويتغير نوع المرجع مع T (مثل HTMLAnchorElement عند استخدام "a").

import React, { forwardRef } from "react"

type OwnProps = { variant?: "solid" | "outline"; children: React.ReactNode }

type PolymorphicProps<T extends React.ElementType, P> = { as?: T } & P & Omit<React.ComponentPropsWithoutRef<T>, keyof P | "as">

const ButtonInner = <T extends React.ElementType = "button">(
  { as, variant = "solid", children, ...rest }: PolymorphicProps<T, OwnProps>,
  ref: React.ForwardedRef<React.ComponentRef<T>>
) => {
  const Component = (as || "button") as React.ElementType
  const style = variant === "outline" ? { border: "1px solid #333", padding: 8 } : { background: "#2563eb", color: "white", padding: 8, borderRadius: 6 }
  return <Component ref={ref} style={style} {...rest}>{children}</Component>
}

export const Button = forwardRef(ButtonInner) as <T extends React.ElementType = "button">(
  props: PolymorphicProps<T, OwnProps> & { ref?: React.Ref<React.ComponentRef<T>> }
) => JSX.Element

أمثلة الاستخدام

عند استخدام as="a"، تصبح الخصائص الأصلية مثل href متاحة، ويُحدَّد نوع المرجع على أنه HTMLAnchorElement.

import React, { useRef } from "react"
import { Button } from "./Button"

export default function App() {
  const btnRef = useRef<HTMLButtonElement>(null)
  const linkRef = useRef<HTMLAnchorElement>(null)

  return (
    <div style={{ display: "grid", gap: 8 }}>
      <Button ref={btnRef} onClick={() => alert("clicked")}>Save</Button>
      <Button as="a" ref={linkRef} href="#docs" variant="outline">Docs</Button>
    </div>
  )
}

التنويعات

يمكنك تغليف المكوّن متعدد الأشكال مع الاحتفاظ بمرونته. استخدم ComponentProps<typeof Button> لتوريث خصائصه.

import React from "react"
import { Button } from "./Button"

export function DangerButton(props: Omit<React.ComponentProps<typeof Button>, "variant">) {
  return <Button {...props} style={{ background: "#dc2626", color: "white", padding: 8, borderRadius: 6 }} />
}

// Works with polymorphism too
export default function App() {
  return (
    <div style={{ display: "grid", gap: 8 }}>
      <DangerButton>Delete</DangerButton>
      <DangerButton as="a" href="#confirm">Delete link</DangerButton>
    </div>
  )
}

نصائح

نصائح:

  • قيّد T إلى React.ElementType.
  • استخدم Omit لحل تعارضات أسماء الخصائص.
  • مرّر المرجع باستخدام forwardRef وحدّد نوعه على أنه React.ComponentRef<T>.

التحقق من الأنواع متعددة الأشكال

تحقق سريع: أي تحديد للنوع يمثّل بشكل صحيح مكوّنًا متعدد الأشكال يمرّر مرجعه؟

مراجعة

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

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

هل درس «المكوّنات متعددة الأشكال؛ خصائص as» مجاني؟

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

ماذا ستتعلم في «المكوّنات متعددة الأشكال؛ خصائص as»؟

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

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

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

كم من الوقت يستغرق درس «المكوّنات متعددة الأشكال؛ خصائص as»؟

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

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

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

← العودة إلى TypeScript Academy