乐闻世界logo
搜索文章和话题

如何在 TypeScript 项目中使用 i18next?

2月18日 22:07

基本类型定义

安装类型定义

bash
npm install --save-dev @types/i18next # 对于 react-i18next npm install --save-dev @types/react-i18next

定义翻译资源类型

typescript
interface TranslationResources { en: { translation: EnTranslation; }; zh: { translation: ZhTranslation; }; } interface EnTranslation { welcome: string; greeting: string; user: { name: string; profile: string; }; } interface ZhTranslation { welcome: string; greeting: string; user: { name: string; profile: string; }; }

使用 useTranslation Hook

基本用法

typescript
import { useTranslation } from 'react-i18next'; function MyComponent() { const { t } = useTranslation(); return <h1>{t('welcome')}</h1>; }

指定命名空间

typescript
function MyComponent() { const { t } = useTranslation('common'); return <button>{t('save')}</button>; }

类型安全的翻译键

typescript
// 定义翻译键类型 type TranslationKeys = 'welcome' | 'greeting' | 'user.name'; function useTypedTranslation() { const { t } = useTranslation(); return { t: (key: TranslationKeys, options?: any) => t(key, options) }; } function MyComponent() { const { t } = useTypedTranslation(); return <h1>{t('welcome')}</h1>; }

创建类型安全的翻译函数

使用泛型

typescript
import i18next from 'i18next'; type TranslationFunction<T> = (key: keyof T, options?: any) => string; function createTypedTranslation<T>(ns: string): TranslationFunction<T> { return (key: keyof T, options?: any) => { return i18next.t(`${ns}:${String(key)}`, options); }; } // 使用 interface CommonTranslations { save: string; cancel: string; delete: string; } const tCommon = createTypedTranslation<CommonTranslations>('common'); function MyComponent() { return ( <div> <button>{tCommon('save')}</button> <button>{tCommon('cancel')}</button> </div> ); }

使用 i18next-resources-to-ts

生成类型定义

bash
npm install --save-dev i18next-resources-to-ts
javascript
// scripts/generate-types.js const { generateTypes } = require('i18next-resources-to-ts'); const fs = require('fs'); generateTypes('./locales', { indent: 2, sort: true, lineEnding: 'lf' }).then(types => { fs.writeFileSync('./src/types/i18n.d.ts', types); console.log('Types generated successfully'); });

在 package.json 中添加脚本

json
{ "scripts": { "generate:i18n-types": "node scripts/generate-types.js" } }

插值类型安全

typescript
interface GreetingOptions { name: string; title?: string; } function useGreeting() { const { t } = useTranslation(); return (options: GreetingOptions) => { return t('greeting', options); }; } function MyComponent() { const greet = useGreeting(); return ( <div> {greet({ name: 'John' })} {greet({ name: 'Jane', title: 'Dr.' })} </div> ); }

复数处理类型

typescript
interface PluralOptions { count: number; item: string; } function usePlural() { const { t } = useTranslation(); return (options: PluralOptions) => { return t('item_count', options); }; } function MyComponent() { const plural = usePlural(); return ( <div> {plural({ count: 1, item: 'apple' })} {plural({ count: 5, item: 'apple' })} </div> ); }

上下文类型

typescript
type Context = 'male' | 'female' | 'other'; interface ContextOptions { context: Context; name: string; } function useContextTranslation() { const { t } = useTranslation(); return (options: ContextOptions) => { return t('friend', options); }; } function MyComponent() { const tFriend = useContextTranslation(); return ( <div> {tFriend({ context: 'male', name: 'John' })} {tFriend({ context: 'female', name: 'Jane' })} </div> ); }

命名空间类型

typescript
interface Namespaces { common: CommonTranslations; errors: ErrorTranslations; user: UserTranslations; } function useNamespacedTranslation<K extends keyof Namespaces>( namespace: K ) { const { t } = useTranslation(namespace); return { t: (key: keyof Namespaces[K], options?: any) => t(key, options) }; } function MyComponent() { const { t: tCommon } = useNamespacedTranslation('common'); const { t: tErrors } = useNamespacedTranslation('errors'); return ( <div> <button>{tCommon('save')}</button> <p>{tErrors('notFound')}</p> </div> ); }

Trans 组件类型

typescript
import { Trans } from 'react-i18next'; interface TransProps { i18nKey: string; values?: Record<string, string | number>; components?: Record<string, React.ReactNode>; } function TypedTrans({ i18nKey, values, components }: TransProps) { return ( <Trans i18nKey={i18nKey} values={values} components={components} /> ); } function MyComponent() { return ( <TypedTrans i18nKey="user.greeting" values={{ name: 'John' }} components={{ strong: <strong /> }} /> ); }

最佳实践

  1. 生成类型: 使用工具自动生成翻译资源类型
  2. 严格模式: 启用 TypeScript 严格模式
  3. 命名空间: 使用命名空间组织翻译
  4. 类型守卫: 使用类型守卫确保类型安全
  5. 持续集成: 在 CI/CD 中生成和检查类型
  6. 文档: 记录类型定义和使用方法
  7. 测试: 编写类型测试确保类型正确性
标签:i18next