Интернационализация (i18n) в TypeScript с библиотекой i18next
Интернационализация (i18n) — это процесс разработки приложения, которое может адаптироваться к различным языкам и региональным стандартам без изменения исходного кода. Для TypeScript-приложений одной из самых мощных и популярных библиотек является i18next. Она поддерживает все современные фреймворки (React, Vue, Angular) и предоставляет первоклассную поддержку TypeScript, что позволяет создавать типобезопасные переводы.
Установка и базовая настройка
Для начала установите пакеты i18next и необходимые бэкенды. В примере ниже используется файловый бэкенд для загрузки JSON-файлов с переводами:
npm install i18next i18next-fs-backend
# Для React дополнительно:
npm install react-i18next
Создайте конфигурационный файл i18n.ts:
import i18n from 'i18next';
import Backend from 'i18next-fs-backend';
import { initReactI18next } from 'react-i18next';
i18n
.use(Backend)
.use(initReactI18next)
.init({
fallbackLng: 'ru',
debug: process.env.NODE_ENV === 'development',
interpolation: {
escapeValue: false,
},
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
});
export default i18n;
Структура файлов переводов
Создайте папку public/locales с подпапками для каждого языка. Например:
public/locales/ru/translation.jsonpublic/locales/en/translation.json
Пример содержимого файла ru/translation.json:
{
"greeting": "Привет, {{name}}!",
"items": "У вас {{count}} сообщение",
"items_plural": "У вас {{count}} сообщений",
"nested": {
"title": "Заголовок",
"description": "Описание"
}
}
Английская версия en/translation.json:
{
"greeting": "Hello, {{name}}!",
"items": "You have {{count}} message",
"items_plural": "You have {{count}} messages",
"nested": {
"title": "Title",
"description": "Description"
}
}
Типизация переводов в TypeScript
Одно из главных преимуществ i18next — строгая типизация. Создайте файл types/i18n.d.ts:
import 'i18next';
declare module 'i18next' {
interface CustomTypeOptions {
defaultNS: 'translation';
resources: {
translation: {
greeting: string;
items: string;
items_plural: string;
nested: {
title: string;
description: string;
};
};
};
}
}
Теперь TypeScript будет проверять ключи переводов на этапе компиляции. Если вы попытаетесь использовать несуществующий ключ, получите ошибку.
Использование в компонентах React
Библиотека react-i18next предоставляет хук useTranslation и компонент Trans:
import { useTranslation } from 'react-i18next';
function Welcome() {
const { t, i18n } = useTranslation();
const changeLanguage = (lng: string) => {
i18n.changeLanguage(lng);
};
return (
<div>
<h2>{t('greeting', { name: 'Иван' })}</h2>
<button onClick={() => changeLanguage('en')}>English</button>
<button onClick={() => changeLanguage('ru')}>Русский</button>
</div>
);
}
Плюризация и интерполяция
i18next поддерживает сложные правила множественного числа. В русском языке три формы (1, 2-4, 5+), в английском — две. Библиотека автоматически выбирает правильную форму на основе числа:
// В файле перевода (ru):
{
"apple": "{{count}} яблоко",
"apple_plural": "{{count}} яблока",
"apple_plural_2": "{{count}} яблок"
}
// Использование:
const message = t('apple', { count: 5 });
// Результат: "5 яблок"
Интерполяция позволяет подставлять переменные в строки перевода. Поддерживаются сложные объекты и функции форматирования:
t('greeting', { name: 'Мария', date: new Date() });
// В JSON: "Привет, {{name}}! Сегодня {{date, datetime}}"