使用 i18next 库在 TypeScript 中实现国际化 (i18n)
国际化 (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: 'Ivan' })}</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