i18next:调用 getFixedT 函数时没有重载匹配此调用

问题描述 投票:0回答:1

我在 TS 应用程序(不是 React)中使用 i18next 库并收到意外的 Typescript 错误。

我在调用

getFixedT
函数时出现类型不匹配。我正在为
lng
ns
传递字符串,但出现预期为
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
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>
}

我初始化

i18nInstance
并导出到这里:

// 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" });

我收到以下 ts 错误:

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)
  • i18下一个版本:^22.4.9
  • os:Mac
typescript i18next overload-resolution
1个回答
2
投票

我能够重现您的问题并发现 2 个问题和一个解决方案 🙃

命名空间<"en"> |空 |未定义

首先,根据 https://www.i18next.com/overview/typescript

resources
应该只包含名称空间(不将它们包装在语言代码中)。例如,您可以使用您的
resources.ts
,并执行:

declare module "i18next" {
    interface CustomTypeOptions {
        // I removed `ns`, as it is not supported in i18n
        returnNull: false;
        resources: typeof resources['en']; // equivalent of typeof { definitions: {...}, errors: {...} }
    }
}

经过上述更改后,我得到了这个错误:

“字符串”类型的参数不可分配给“`命名空间”类型的参数<"definitions" | "errors"> |空 |未定义'.ts(2769)

剩下的问题是 TypeScript 无法推断您的命名空间键的类型(每个键都被视为纯字符串,而不是文字值)。我们可以用

as const
解决这个问题:

// As const
export const NAMESPACES = {
  definitions: "definitions",
  errors: "errors",
} as const;
© www.soinside.com 2019 - 2024. All rights reserved.