IT
🔧

عامل satisfies في TypeScript 5.5 — الدليل الشامل للاستخدام والفوارق عن as

USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。

عامل satisfies في TypeScript 5.5 — الدليل الشامل للاستخدام والفوارق عن as

ملخص

person holding paper near pen
  • عامل satisfies يسمح بالتحقق من توافق الأنواع دون فقدان معلومات النوع الدقيق.
  • يختلف عن as في أنه لا يُجبر TypeScript على قبول نوع خاطئ — بل يتحقق منه بأمان.
  • مثالي للتعامل مع كائنات التكوين والقواميس والقيم ذات الأنواع المتحدة.

جدول المحتويات

low angle photo city high rise buildings during daytime

ما هو عامل satisfies؟ {#section1}

person putting money business finance

المشكلة التي يحلها

قبل satisfies، عند التعامل مع كائنات القاموس أو التكوين كنت أمام خيارين إما:

typescript
// 1. التعريف الصريح للنوع — يفقد معلومات النوع الدقيق
const palette: Record<string, string | number[]> = {
  red: [255, 0, 0],
  green: '#00ff00',
}
// الآن palette.red هو string | number[] وليس number[]

// 2. الاستنتاج التلقائي — لا تحقق من توافق النوع
const palette = {
  red: [255, 0, 0],
  green: '#00ff00',
}
// لا يوجد تحقق من توافق النوع مع Record<string, string | number[]>

الحل مع satisfies

typescript
const palette = {
  red: [255, 0, 0],
  green: '#00ff00',
} satisfies Record<string, string | number[]>

// الآن:
// - يتحقق TypeScript من توافق الكائن مع Record<string, string | number[]>
// - palette.red هو number[] (النوع الدقيق محفوظ)
// - palette.green هو string (النوع الدقيق محفوظ)
palette.red.map(v => v * 2)  // ✅ يعمل، red هو number[]
palette.green.toUpperCase()  // ✅ يعمل، green هو string

الفرق بين satisfies وas والتعريف الصريح للنوع {#section2}

as — إجبار على النوع (خطر)

typescript
const value = 'hello' as number  // ✅ يمر TypeScript بدون خطأ
// لكن في وقت التشغيل سيكون 'hello' وليس رقمًا

// as يتجاوز فحص TypeScript — ينبغي استخدامه فقط حين تكون واثقًا تمامًا

التعريف الصريح للنوع — يفقد الدقة

typescript
const config: { mode: 'dark' | 'light' } = { mode: 'dark' }
// config.mode هو 'dark' | 'light' وليس 'dark' حصرًا
// فقدنا معرفة أن القيمة الفعلية هي 'dark'

satisfies — الأفضل من العالمين

typescript
const config = { mode: 'dark' } satisfies { mode: 'dark' | 'light' }
// config.mode هو 'dark' (النوع الحرفي محفوظ)
// يتحقق TypeScript من أن 'dark' يتوافق مع 'dark' | 'light'

حالات الاستخدام الشائعة {#section3}

1. كائنات التكوين

typescript
const dbConfig = {
  host: 'localhost',
  port: 5432,
  ssl: true,
} satisfies {
  host: string
  port: number
  ssl?: boolean
}
// يُتحقق من التوافق مع هيكل الكائن
// لكن dbConfig.port هو 5432 (رقم حرفي) وليس number فقط

2. متغيرات CSS أو الألوان

typescript
type Color = `#${string}` | [number, number, number]

const theme = {
  primary: '#3b82f6',
  secondary: [59, 130, 246],
  accent: '#6366f1',
} satisfies Record<string, Color>

// theme.primary هو '#3b82f6' (نوع حرفي دقيق)
// theme.secondary هو [number, number, number] (tuple)

3. ترجمات متعددة اللغات

typescript
type Lang = 'en' | 'ko' | 'ja'
type Translations = Record<Lang, { greeting: string; farewell: string }>

const messages = {
  en: { greeting: 'Hello', farewell: 'Goodbye' },
  ko: { greeting: 'Annyeonghaseyo', farewell: 'Annyeonghi gaseyo' },
  ja: { greeting: 'こんにちは', farewell: 'さようなら' },
} satisfies Translations

// TypeScript يتحقق من وجود جميع اللغات المطلوبة
// كل قيمة تحتفظ بنوعها الدقيق

أمثلة عملية في مشاريع حقيقية {#section4}

مثال React — تكوين الثيم

typescript
const theme = {
  colors: {
    primary: '#3b82f6',
    success: '#10b981',
    warning: '#f59e0b',
    danger: '#ef4444',
  },
  spacing: {
    sm: 8,
    md: 16,
    lg: 24,
    xl: 32,
  },
} satisfies {
  colors: Record<string, `#${string}`>
  spacing: Record<string, number>
}

// theme.colors.primary هو '#3b82f6' تحديدًا
// theme.spacing.md هو 16 تحديدًا

مثال Next.js — تعريف المسارات

typescript
const routes = {
  home: '/',
  blog: '/blog',
  tools: '/tools',
  about: '/about',
} satisfies Record<string, `/${string}`>

// TypeScript يتحقق من أن جميع المسارات تبدأ بـ /
// routes.home هو '/' (نوع حرفي دقيق)

مثال API — تعريف استجابة

typescript
type ApiResponse<T> = {
  data: T
  status: 200 | 201 | 400 | 404 | 500
  message: string
}

const userResponse = {
  data: { id: 1, name: 'Ahmed' },
  status: 200,
  message: 'Success',
} satisfies ApiResponse<{ id: number; name: string }>

// userResponse.status هو 200 (ليس 200 | 201 | 400 | 404 | 500)

متى لا تستخدم satisfies {#section5}

عند الحاجة إلى نوع أشمل

typescript
// إذا كنت تريد قيمة النوع الأشمل للواجهة
function processConfig(config: Record<string, string | number>) {
  // ...
}

const myConfig: Record<string, string | number> = { port: 3000 }
// هنا التعريف الصريح للنوع أنسب من satisfies

عند كتابة النوع صعبًا تقنيًا

إذا كان تعريف النوع طويلًا ومعقدًا جدًا مقابل الفائدة المحققة، فقد يكون التعريف الصريح للنوع أوضح وأسهل في الصيانة.

ملخص الخبراء

  • satisfies أفضل من as في أغلب الحالات لأنه يتحقق من النوع دون إجباره.
  • استخدمه مع كائنات التكوين والقواميس والكائنات المعقدة.
  • يحافظ على النوع الحرفي الدقيق في حين يتحقق من توافق الهيكل.
  • متوفر منذ TypeScript 4.9، ولكنه استقر واستُحسن في 5.x.

الخلاصة

عامل satisfies يحل توترًا قديمًا في TypeScript بين الدقة والتحقق. استخدمه متى أردت التحقق من أن كائنًا يتوافق مع نوع ما مع الاحتفاظ بأدق تعريف ممكن للنوع. هذا النمط يُحسّن سلامة الكود دون التضحية بتجربة المطور.

الأسئلة الشائعة (FAQ)

س. هل satisfies متوفر في الإصدارات القديمة من TypeScript؟ ج. تم تقديمه في TypeScript 4.9. إذا كنت تستخدم إصدارًا أقدم، فلن يعمل.

س. هل يمكن استخدام satisfies مع const assertion (as const)؟ ج. نعم، ويمكن الجمع بينهما: const x = { mode: 'dark' } as const satisfies { mode: 'dark' | 'light' }.

س. هل satisfies أبطأ في وقت الترجمة من as؟ ج. قد يضيف تحققًا إضافيًا بسيطًا، لكن الفارق في وقت الترجمة ضئيل في المشاريع العادية.

س. هل أستخدم satisfies أو Zod للتحقق من البيانات الخارجية؟ ج. satisfies للتحقق في وقت الترجمة فقط، بينما Zod للتحقق في وقت التشغيل أيضًا. لبيانات API الخارجية، استخدم Zod أو مكتبة مماثلة.

س. ما الفرق بين satisfies وGenerics؟ ج. الـ Generics للدوال والأنواع القابلة لإعادة الاستخدام، بينما satisfies للتحقق من نوع تعبير أو كائن محدد.

🔧 Related Free Tools

ذو صلة