Typesafe-i18n مع TypeScript: دليل شامل مع أمثلة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Typesafe-i18n: التدويل مع دعم كامل للأنواع في TypeScript

في تطوير الويب الحديث، التدويل (i18n) ليس مجرد ترجمة للنصوص، بل هو نظام متكامل لإدارة التوطين. Typesafe-i18n هي مكتبة خاصة بـ TypeScript ترفع مستوى التدويل إلى مرحلة جديدة، حيث توفر أمانًا كاملاً للأنواع في جميع المراحل: من كتابة الترجمات إلى استخدامها في الكود.

لماذا تحتاج هذه المكتبة؟ الحلول التقليدية للتدويل (مثل i18next) غالبًا ما تعمل مع نصوص ديناميكية، مما يؤدي إلى أخطاء: أخطاء إملائية في المفاتيح، وسيطات غير صحيحة، أو ترجمات مفقودة. Typesafe-i18n تحل هذه المشكلة بشكل جذري: إذا كتبت LL.WELCOME({name: "أحمد"})، سيتحقق TypeScript من وجود المفتاح WELCOME، ومن قبوله للمعامل name، ومن نوع هذا المعامل. أخطاء التوطين تصبح أخطاء ترجمة (compile-time) وليست أخطاء وقت التشغيل (runtime).

المكتبة مثالية للمشاريع التي تتطلب كتابة أنواع صارمة: تطبيقات React/Vue/Angular، خوادم Node.js، ومكتبات المكونات. تدعم الجمع، الإقحام (interpolation)، المفاتيح المتداخلة، التحميل غير المتزامن، وتوليد الأنواع بناءً على ملفات الترجمات الخاصة بك. في هذه المقالة، سنستعرض جميع جوانب العمل مع Typesafe-i18n: من التثبيت إلى التقنيات المتقدمة.

التثبيت

يتم التثبيت عبر npm (أو yarn/pnpm):

npm install typesafe-i18n

لتوليد الأنواع وملفات الترجمات، ستحتاج إلى حزمة إضافية:

npm install --save-dev typesafe-i18n-cli

بعد التثبيت، قم بتهيئة المشروع:

npx typesafe-i18n --init

سينشئ هذا الأمر هيكل المجلدات الأساسي وملفات الإعدادات.

بداية سريعة: مثال عملي بسيط

لننشئ تطبيقًا بسيطًا يرحب بالمستخدم بلغات مختلفة.

الخطوة 1: إنشاء ملف الترجمة

أنشئ ملفًا باسم src/i18n/en/index.ts:

import type { Translation } from '../i18n-types'

const en: Translation = {
   HI: 'Hello {name}!',
   GOODBYE: 'Goodbye, {name}!'
}

export default en

الخطوة 2: إنشاء ملف الترجمة للغة العربية

أنشئ ملفًا باسم src/i18n/ar/index.ts:

import type { Translation } from '../i18n-types'

const ar: Translation = {
   HI: 'مرحبًا {name}!',
   GOODBYE: 'إلى اللقاء، {name}!'
}

export default ar

الخطوة 3: تشغيل توليد الأنواع

npx typesafe-i18n

الخطوة 4: الاستخدام في الكود

import { i18n } from './i18n/i18n-util'
import { loadLocale } from './i18n/i18n-util.sync'
import { L } from './i18n/i18n-util'

// تحميل اللغات
loadLocale('en')
loadLocale('ar')

// إنشاء كائن للغة الإنجليزية
const LL_en = i18n('en')
console.log(LL_en.HI({ name: 'Alex' })) // الإخراج: Hello Alex!

// التبديل إلى العربية
const LL_ar = i18n('ar')
console.log(LL_ar.HI({ name: 'أحمد' })) // الإخراج: مرحبًا أحمد!

لاحظ: إذا حاولت استدعاء LL_en.HI() بدون المعامل name، سيصدر TypeScript خطأ في الترجمة. وإذا أخطأت في كتابة المفتاح (LL_en.Hello)، سيظهر خطأ أيضًا.

الدوال والطرق الأساسية

دعنا نستعرض 8 دوال وطرق رئيسية في مكتبة Typesafe-i18n.

1. i18n(locale: Locales): TranslationFunctions

التوقيع: i18n(locale: Locales): TranslationFunctions

الوظيفة: تنشئ كائن ترجمة للغة المحددة. تُرجع كائنًا يحتوي على جميع دوال الترجمة.

const LL = i18n('ar')
console.log(LL.HI({ name: 'سارة' })) // مرحبًا سارة!

2. loadLocale(locale: Locales): void

التوقيع: loadLocale(locale: Locales): void

الوظيفة: تحميل ملفات الترجمة للغة محددة بشكل متزامن (synchronous).

loadLocale('en')
loadLocale('ar')

3. loadLocaleAsync(locale: Locales): Promise<void>

التوقيع: loadLocaleAsync(locale: Locales): Promise<void>

الوظيفة: تحميل ملفات الترجمة بشكل غير متزامن (asynchronous). مفيد للتطبيقات الكبيرة.

await loadLocaleAsync('ar')

4. detectLocale(): Locales

التوقيع: detectLocale(): Locales

الوظيفة: كشف لغة المستخدم تلقائيًا بناءً على إعدادات المتصفح أو النظام.

const userLocale = detectLocale()
const LL = i18n(userLocale)

5. isLocale(locale: string): locale is Locales

التوقيع: isLocale(locale: string): locale is Locales

الوظيفة: التحقق مما إذا كانت السلسلة النصية تمثل لغة مدعومة في المشروع.

if (isLocale('ar')) {
   const LL = i18n('ar')
}

6. getLocale(): Locales

التوقيع: getLocale(): Locales

الوظيفة: إرجاع اللغة النشطة حاليًا.

const currentLocale = getLocale() // 'ar' مثلاً

7. setLocale(locale: Locales): void

التوقيع: setLocale(locale: Locales): void

الوظيفة: تغيير اللغة النشطة ديناميكيًا.

setLocale('en')
const LL = i18n('en')

8. L (كائن الأنواع)

التوقيع: L: Locales

الوظيفة: كائن يحتوي على جميع اللغات المدعومة كأنواع، مما يسهل التبديل بينها بأمان.

import { L } from './i18n/i18n-util'
const locale: Locales = L.ar // 'ar' مع دعم كامل للأنواع

الخلاصة

Typesafe-i18n هي أداة قوية تجعل التدويل في TypeScript آمنًا وسهلًا. بفضل دعمها الكامل للأنواع، يمكنك تجنب أخطاء وقت التشغيل وبناء تطبيقات متعددة اللغات بثقة. جربها في مشروعك القادم!

توصيات