TypeScript

TypeScript لمطوري React

الأنماط الرئيسية لكتابة أنواع المكونات، والخطافات، والسياق دون عناء.

١٠ نوفمبر ٢٠٢٥
4 دقيقة قراءة
بواسطة useLines Team
TypeScriptReactTypesHooks
Illustration for TypeScript لمطوري React

TypeScript لـ React، باختصار

يجعل TypeScript تطبيقات React أكثر أمانًا وأسهل في العمل عليها. تحصل على أخطاء واضحة، وإكمال تلقائي رائع، وكود يوثق نفسه. ابدأ صغيرًا، وأضف الأنواع حيث تساعد، وتوسع من هناك.

لماذا يساعد

  • اكتشاف الأخطاء قبل وقت التشغيل (على سبيل المثال، "الكائن ربما غير محدد")
  • الإكمال التلقائي للدعائم، والحالة، واستجابات API
  • إعادة بناء آمنة وواجهات برمجة تطبيقات أوضح

ما يجب كتابة أنواعه أولاً

  • دعائم المكونات والأحداث
  • استجابات API وحالة النموذج
  • الأدوات المساعدة القابلة لإعادة الاستخدام (مع الأنواع العامة)

مثال بسيط

interface ButtonProps { label: string; onClick?: () => void }
export function Button({ label, onClick }: ButtonProps) {
  return <button onClick={onClick}>{label}</button>;
}

نصائح عملية

  • فضل interface للكائنات؛ type للاتحادات/الأسماء المستعارة
  • تجنب any؛ استخدم unknown أو الأنواع العامة
  • أعد نتائج مكتوبة من مساعدي API
  • لا تفرط في كتابة الأنواع؛ حافظ على قابليتها للقراءة

خلاصة القول

ابدأ بأنواع الدعائم وواجهات برمجة التطبيقات، ثم أضف المزيد حيث يقلل من الأخطاء ويحسن تجربة المطور.

export function useLocalStorage<T>(key: string, initial: T) {
  const [value, setValue] = React.useState<T>(() => {
    const raw = localStorage.getItem(key);
    return raw ? (JSON.parse(raw) as T) : initial;
  });
  React.useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);
  return [value, setValue] as const;
}

السياق مع المحددات

تجنب إعادة عرض جميع المستهلكين عن طريق كشف خطافات المحدد:

type State = { theme: "light" | "dark"; user?: { id: string; name: string } };
const AppState = React.createContext<State | null>(null);

export function useTheme() {
  const ctx = React.useContext(AppState);
  if (!ctx) throw new Error("useTheme must be used within provider");
  return ctx.theme;
}

أنماط المكونات

  • اتحادات مميزة للمكونات ذات المتغيرات الثقيلة
  • أنواع قوالب حرفية لأسماء الفئات والرموز
  • أنواع الأدوات المساعدة (Pick, Omit, ReturnType) لتكوين واجهات برمجة التطبيقات
type Variant = "primary" | "secondary" | "ghost";
type Size = "sm" | "md" | "lg";

type ButtonProps = {
  variant?: Variant;
  size?: Size;
} & React.ButtonHTMLAttributes<HTMLButtonElement>;

export const Button: React.FC<ButtonProps> = ({
  variant = "primary",
  size = "md",
  ...rest
}) => {
  const cls = `btn ${variant} ${size}` as const;
  return <button className={cls} {...rest} />;
};

اختبار الأنواع

استخدم tsd أو expectTypeOf لقفل عقود الأنواع في المكتبات. في التطبيقات، فضل الخيارات الصارمة في tsconfig وأبقِ any خارج المسارات الساخنة.

الخلاصة

اكتب أنواع السطح العام، واكشف عن خطافات/محددات ضيقة، واستخدم الاتحادات/الأنواع العامة للحفاظ على المكونات معبرة وآمنة.

الأنماط المتقدمة

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

type AsProp<C extends React.ElementType> = {
  as?: C;
};

type PolymorphicProps<C extends React.ElementType, P> = AsProp<C> &
  Omit<React.ComponentPropsWithoutRef<C>, keyof AsProp<C>> &
  P;

export function Text<C extends React.ElementType = "span">({
  as,
  children,
  ...rest
}: PolymorphicProps<C, { weight?: "regular" | "bold" }>) {
  const Component = (as || "span") as React.ElementType;
  return <Component {...rest}>{children}</Component>;
}

فحوصات الشمولية

type Status = "idle" | "loading" | "success" | "error";

function assertNever(x: never): never {
  throw new Error(`Unhandled: ${x}`);
}

function statusToColor(s: Status) {
  switch (s) {
    case "idle":
      return "gray";
    case "loading":
      return "blue";
    case "success":
      return "green";
    case "error":
      return "red";
    default:
      return assertNever(s);
  }
}

مساعدات الاستدلال

استخدم satisfies للحفاظ على التوسيع تحت السيطرة والحفاظ على الأنواع الحرفية.

const routes = {
  home: "/",
  blog: "/blog",
  post: (slug: string) => `/post/${slug}`,
} as const satisfies Record<string, unknown>;