基本类型定义
安装类型定义
npm install --save-dev @types/i18next
# 对于 react-i18next
npm install --save-dev @types/react-i18next
定义翻译资源类型
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
基本用法
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation();
return <h1>{t('welcome')}</h1>;
}
指定命名空间
function MyComponent() {
const { t } = useTranslation('common');
return <button>{t('save')}</button>;
}
类型安全的翻译键
// 定义翻译键类型
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>;
}
创建类型安全的翻译函数
使用泛型
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
生成类型定义
npm install --save-dev i18next-resources-to-ts
// 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 中添加脚本
{
"scripts": {
"generate:i18n-types": "node scripts/generate-types.js"
}
}
插值类型安全
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>
);
}
复数处理类型
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>
);
}
上下文类型
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>
);
}
命名空间类型
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 组件类型
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 /> }}
/>
);
}
最佳实践
- 生成类型: 使用工具自动生成翻译资源类型
- 严格模式: 启用 TypeScript 严格模式
- 命名空间: 使用命名空间组织翻译
- 类型守卫: 使用类型守卫确保类型安全
- 持续集成: 在 CI/CD 中生成和检查类型
- 文档: 记录类型定义和使用方法
- 测试: 编写类型测试确保类型正确性