useTranslation Hook 的自动完成功能不适用于不同的命名空间

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

我正在使用 React-i18next

^15.1.0
和 Typescript
^5.6.3
并尝试使自动完成功能正常工作。我已经遵循了教程(https://locize.com/blog/i18next-typescript/)和(https://www.i18next.com/overview/typescript)。

通过在

i18next.d.ts
文件中导入翻译资源的简单配置不起作用后,我决定尝试更复杂的方法来使用
i18next-resources-for-ts interface -i ./locales/en -o ./@types/resources.d.ts
命令行,以生成涵盖更多用例的界面。

现在我的自动完成功能几乎可以工作了,但我只获得了默认命名空间的自动完成功能,但其他命名空间不可用。不仅自动补全不起作用,而且我现在还收到 TS 错误:

t("timesheet:placeholder.What are you working on")

Type '"timesheet:placeholder.What are you working on"' is not assignable to type '"common.Case" | "common.Code" | "common.Price" | "common.Qty" | "common.Select Case" | "common.Select Code" | "common.Total" | "common.Unit" | TemplateStringsArray | ("common.Case" | ... 7 more ... | TemplateStringsArray)[]'

另一个奇怪的行为是,如果我将

defaultNS
更改为
timesheet
,那么我只有
timesheet
命名空间工作,而不是
translation
命名空间。

为了让所有命名空间都可用作类型,我缺少什么?

这是我的配置:

i18n.ts

import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";

import TIMESHEET_DE from "@/locales/de/timesheet.json";
import TRANSLATION_DE from "@/locales/de/translation.json";
import TIMESHEET_EN from "@/locales/en/timesheet.json";
import TRANSLATION_EN from "@/locales/en/translation.json";
import TIMESHEET_FR from "@/locales/fr/timesheet.json";
import TRANSLATION_FR from "@/locales/fr/translation.json";
import TIMESHEET_IT from "@/locales/it/timesheet.json";
import TRANSLATION_IT from "@/locales/it/translation.json";

const resources = {
  en: {
    translation: TRANSLATION_EN,
    timesheet: TIMESHEET_EN,
  },
  fr: {
    translation: TRANSLATION_FR,
    timesheet: TIMESHEET_FR,
  },
  it: {
    translation: TRANSLATION_IT,
    timesheet: TIMESHEET_IT,
  },
  de: {
    translation: TRANSLATION_DE,
    timesheet: TIMESHEET_DE,
  },
} as const;

const defaultNS = "translation";
const ns = ["translation", "timesheet"];

i18n
  // detect user language
  // learn more: https://github.com/i18next/i18next-browser-languageDetector
  .use(LanguageDetector)
  .use(initReactI18next)
  // for all options read: https://www.i18next.com/overview/configuration-options
  .init({
    returnEmptyString: false,
    debug: import.meta.env.DEV,
    fallbackLng: "en",
    lng: "en",
    defaultNS,
    ns,
    interpolation: {
      escapeValue: false, // not needed for react as it escapes by default
    },
    resources: resources,
  });

export default i18n;
export { defaultNS, ns, resources };

i18next.d.ts

import type Resources from "./resources";

import { defaultNS, ns } from "@/i18n";

declare module "i18next" {
  interface CustomTypeOptions {
    resources: Resources;
    defaultNS: typeof defaultNS;
    ns: typeof ns;
  }
}

resources.d.ts

interface Resources {
  "timesheet": {
    "placeholder": {
      "What are you working on": ""
    }
  },
  "translation": {
    "common": {
      "Case": "Case",
      "Code": "Code",
      "Price": "Price",
      "Qty": "Qty",
      "Select Case": "Select Case",
      "Select Code": "Select Code",
      "Total": "Total",
      "Unit": "Unit"
    }
  }
}

export default Resources;
reactjs typescript autocomplete i18next react-i18next
1个回答
0
投票

我实际上会回答我自己的问题,因为我已经找到了答案。

棘手的部分实际上在本教程中的某个地方。

解决问题的部分是:

在新的react-i18next版本中,当加载多个命名空间时,t函数将推断并接受第一个命名空间的键。所以现在这种模式被接受了:

const {t} = useTranslation(['ns1', 'ns2']);

所以实际上我们必须告诉

useTranslation
我们要使用哪个命名空间,以便
t
能够正确键入。

© www.soinside.com 2019 - 2024. All rights reserved.