我正在努力正确扩展该功能。我遇到了错误
Cannot redeclare block-scoped variable t
。我不太确定声明模块是否是正确的方法(我是 ts 新手)。我还尝试了为 t 函数创建一个包装器的想法,然后使用该包装器并且不会出现重新声明的错误。但我无法为此创建一个工作示例。
抑制错误 // @ts-ignore 会导致我从 json 文件中获得有效键的正确建议,但如果我输入不存在的键,则不会进行验证
我创建了一个文件 i18n.d.ts,如下所示
import "react-i18next";
import deTranslation from 'src/translation/de-translation.json';
declare module 'i18next' {
type Translations<T = typeof deTranslation> = T;
type ConcatKeys<T, U> = T extends string ? `${T & string}.${U & string}` : never;
type NestedKeys<T> =
T extends object ? {
[K in keyof T]: K | ConcatKeys<K, NestedKeys<T[K]>>;
}[keyof T] :
string;
type TranslationKeys<T> = NestedKeys<T>;
interface TranslationFunction<T> {
<K extends TranslationKeys<T>>(key: K, nestedKeys?: string[]): string;
}
export const t: TranslationFunction<Translations>;
}
我的目标是能够像这样使用它
t('property.mortgage.mortgage_status')}
,如果 de-translation.json 文件中不存在该密钥,则可以获得有关密钥和验证的建议。
我想出了一个可能的解决方案。
将 I18n 接口添加到模块声明中,并使用项目中 i18n 中使用的属性和方法。然后导出就解决了问题。 t 函数现在是类型安全的并且具有正确的建议。
这种方案的缺点是你必须手动将新使用的功能添加到界面中。
interface I18n {
language: string;
changeLanguage: (lang: string) => Promise<void>;
use: (module: any) => I18n;
t: TranslationFunction<Translations>;
init: (options: any) => Promise<I18n>;
// Add other properties/methods you use from i18n
}
const i18n: I18n & {
t: TranslationFunction<Translations>;
};