调用i18next的getFixedT函数出现TypeScript类型不匹配错误
非React TypeScript项目中i18next getFixedT类型不匹配问题
在非React的TypeScript项目中使用i18next(版本^22.4.9)时,调用getFixedT传入lng和ns字符串参数,触发TypeScript类型错误,提示期望接收null值。
重现步骤
类型定义(i18next.d.ts)
// i18next.d.ts import "i18next"; import definitions from "../i18n/locales/definitions/en.json"; import errors from "../i18n/locales/errors/en.json"; const NAMESPACES = { definitions: "definitions", errors: "errors", }; declare module "i18next" { interface CustomTypeOptions { ns: typeof NAMESPACES.errors | typeof NAMESPACES.definitions; returnNull: false; resources: { en: { definitions: typeof definitions; errors: typeof errors; } }; } }
资源文件(src/i18n/locales/resources.ts)
// src/i18n/locales/resources.ts import definitions_de from './definitions/de.json'; import definitions_en from './definitions/en.json'; import errors_de from './errors/de.json'; import errors_en from './errors/en.json'; export const resources = { de: { definitions: definitions_de, errors: errors_de, }, en: { definitions: definitions_en, errors: errors_en, }, // <etc> }
i18n初始化(src/i18n/index.ts)
// src/i18n/index.ts import i18n, { createInstance, InitOptions } from 'i18next'; import { fallbackLng, NAMESPACES } from '../constants'; import { resources } from './locales/resources'; const i18nInstance = createInstance(); void i18nInstance .init({ fallbackLng, // use en if detected language is not available defaultNS: NAMESPACES.errors, resources, load: 'currentOnly', // only load the detected language ns: [NAMESPACES.definitions, NAMESPACES.errors], // namespaces saveMissing: true, // send not translated keys to endpoint returnNull: false, } as InitOptions); export default i18nInstance;
调用getFixedT的代码
const locale = "en"; const t = i18nInstance.getFixedT(locale, NAMESPACES.errors) t("path.to.definition", { variable: "value" });
TypeScript错误信息
No overload matches this call. Overload 1 of 2, '(lng: null, ns: Namespace<"en"> | null, keyPrefix?: KeyPrefix<Namespace<"en">>): TFunction<Namespace<"en">, KeyPrefix<Namespace<"en">>, Namespace<...>>', gave the following error. Argument of type 'Locale' is not assignable to parameter of type 'null'. Type '"de"' is not assignable to type 'null'. Overload 2 of 2, '(lng: string | readonly string[], ns?: Namespace<"en"> | null | undefined, keyPrefix?: undefined): TFunction<Namespace<"en">, undefined, Namespace<"en">>', gave the following error. Argument of type 'string' is not assignable to parameter of type 'Namespace<"en"> | null | undefined'.ts(2769)
环境信息
- i18next版本:^22.4.9
- 操作系统:Mac
解决方案
1. 完善CustomTypeOptions类型定义
原定义仅声明了en语言的资源,导致TypeScript无法识别其他支持语言,同时缺少supportedLngs字段明确语言范围。修改i18next.d.ts:
// i18next.d.ts import "i18next"; import definitions_en from "../i18n/locales/definitions/en.json"; import errors_en from "../i18n/locales/errors/en.json"; import definitions_de from "../i18n/locales/definitions/de.json"; import errors_de from "../i18n/locales/errors/de.json"; const NAMESPACES = { definitions: "definitions", errors: "errors", }; // 定义所有支持的语言类型 type SupportedLngs = "en" | "de"; declare module "i18next" { interface CustomTypeOptions { // 简洁声明命名空间类型 ns: typeof NAMESPACES[keyof typeof NAMESPACES]; returnNull: false; // 明确支持的语言列表 supportedLngs: SupportedLngs; // 映射所有支持语言的资源类型 resources: { [lng in SupportedLngs]: { definitions: typeof definitions_en | typeof definitions_de; errors: typeof errors_en | typeof errors_de; } }; } }
2. 移除强制类型转换,保留类型推导
初始化时使用as InitOptions会丢失类型检查,导致i18n实例无法正确继承自定义类型配置。修改src/i18n/index.ts:
// src/i18n/index.ts import i18n, { createInstance } from 'i18next'; import { fallbackLng, NAMESPACES } from '../constants'; import { resources } from './locales/resources'; const i18nInstance = createInstance(); void i18nInstance.init({ fallbackLng, defaultNS: NAMESPACES.errors, resources, load: 'currentOnly', ns: [NAMESPACES.definitions, NAMESPACES.errors], saveMissing: true, returnNull: false, }); export default i18nInstance;
3. 限定locale参数的类型
确保调用getFixedT时的locale类型为SupportedLngs,避免TypeScript将其推断为宽泛的string类型:
import type { SupportedLngs } from './path/to/i18next.d.ts'; const locale: SupportedLngs = "en"; const t = i18nInstance.getFixedT(locale, NAMESPACES.errors); // 注意:key需对应errors命名空间下的实际路径,避免无效key报错 t("path.to.error", { variable: "value" });
内容的提问来源于stack exchange,提问作者bildungsroman
相关产品推荐
相关产品推荐

