typescript 如何从字符串数组中推断类型?

gzjq41n4  于 2023-02-25  发布在  TypeScript
关注(0)|答案(2)|浏览(139)

下一个-i18下一个配置. js

const nextI18NextConfig = {
  i18n: {
    defaultLocale: "fr",
    locales: ["en", "fr"],
    reloadOnPrerender: process.env.NODE_ENV === "development",
  },
}

module.exports = nextI18NextConfig

主题. json

{
  "feedback-introduction": {
    "fr": {
      "name": "Introduction à la rétroaction"
    },
    "en": {
      "name": "Introduction to feedback"
    }
  }
}

主题. tsx

…
import i18n from "./next-i18next.config.js"
import topics from "./topics.json"

export default () => {
  const { locale } = useRouter()
  const { t } = useTranslation("common")
  var localizedTopics: string[] = []
  for (const [slug, topic] of Object.entries(topics)) {
    localizedTopics.push(topic[locale as "en" | "fr"].name)
  }
  …
}

我不想使用locale as "en" | "fr",而是想通过编程从next-i18next.config.js中的locales推断"en" | "fr"
这可能吗?

hwamh0ep

hwamh0ep1#

可以从另一个文件中通过编程推断出i18n.locales的类型吗?
简而言之:如果导出源没有提供您想要的文本类型信息,那么编译器将无法使用它。
如果导出文件提供了字符串类型信息,则数组的数字索引处的字符串类型可以是inferred,否则,数组元素类型将使用手册中描述的最佳通用类型进行推断。
下面是一个例子:
TSPlayground

// import {array1} from "./some_module.js";
const array1 = ["a", "b", "c"];
type Element1 = typeof array1[number];
   //^? type Element1 = string

const array2 = ["a", "b", "c"] as const;
type Element2 = typeof array2[number];
   //^? type Element2 = "a" | "b" | "c"

const array3: ("a" | "b" | "c" | "d")[] = ["a", "b", "c"];
type Element3 = typeof array3[number];
   //^? type Element3 = "a" | "b" | "c" | "d"
gtlvzcf8

gtlvzcf82#

如果你有import i18n from "./next-i18next.config.js",那么文件 * 是 * 在你的控制之下。如果出于某种原因,它必须是JS而不是TS,但你可以改变文件本身,它可能是可能的使用https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html。但我一直无法让它工作。

const en = /** @type {const} */("en");
const fr = /** @type {const} */("fr");

const locales = /** @type {const} */([en, fr]);

const nextI18NextConfig = /** @type {const} */({
  i18n: {
    defaultLocale: "fr",
    locales: ["en", "fr"],
    reloadOnPrerender: false,
  },
});

Playground
您可以看到enfr具有所需的类型,但它不适用于localesnextI18NextConfig,而且我无法找到适用的语法。
相反,我的建议是使用as const在TS文件中定义配置,然后./next-i18next.config.js可以简单地导入和重新导出它。

相关问题