typescript:如何将类型定义为枚举的任何部分?

x3naxklr  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(386)

我正在尝试使用typescript创建翻译模块。
我想将语言定义为创建文本函数的枚举参数,如下所示:

export enum Language {
    He = "he",
    En = "en",
}
const { createI18n, createI18nText } = createTextFunctions(Language);
const firstExample = createI18nText({
    he: {
        firstText: "שלום",
        sc: {
            hello: "שלום שוב"
        }
    },
    en: {
        firstText: "hello",
        sc: {
            hello: "hello again"
        }
    }
})
export const i18n = createI18n({
    welcome: firstExample,

})

但我的问题是,因为语言是作为参数传递给typescript函数的,并且该函数会推断类型,所以typescript不会引起任何警告。我可以用不存在的语言创建文本,它会传递它,就像 createI18nText({ ar:{ hi : "hi" }}) .
我的文本功能如下:

export type Languages = { [key: string]: string };
export const createTextFunctions = (languages: LanguagesD) => {

    type I18nText<T extends object> = {
        [k in keyof typeof languages]: T;
    }

    const createI18n = <T extends { [key: string]: I18nText<any>; }>(i18n: T) => {
        return i18n;
    };

    const createI18nText = <T extends object>(text: I18nText<T>) => {
        return text;
    }

    return {
        createI18n,
        createI18nText
    }
}

因此,代码正在运行并执行它需要执行的任何操作,但我正在失去类型控制。
我更喜欢使用小写的枚举值,所以这也是一个问题。如果这是解决方案,那么我就采用它,但是如果有任何方法可以传递枚举参数并按其值运行,那就太好了。

x33g5p2x

x33g5p2x1#

你可以 createTextFunctions 使用泛型。创建文本功能时,您可以根据需要自定义键:

// *L* must be a union of strings.
const createTextFunctions = <L extends string>() => {

    type I18nText<T extends object> = Record<L, T>;
    type I18n = Record<string, I18nText<any>>;

    const createI18n = <T extends I18n>(i18n: T): T => {
        return i18n;
    };

    const createI18nText = <T extends object>(text: I18nText<T>): I18nText<T> => {
        return text;
    }

    return {
        createI18n,
        createI18nText
    }
}

然后指定 Language 作为字符串的并集:

type Language = "en" | "he";

和创建/使用文本功能:

const { createI18n, createI18nText } = createTextFunctions<Language>();

const firstExample = createI18nText({
  he: {
    firstText: "שלום",
    sc: {
      hello: "שלום שוב"
    }
  },
  // If the key *en* is missing, typescript will complain.
  en: {
    firstText: "hello",
    sc: {
      hello: "hello again"
    }
  },
  // If we add the key *us*, typescript will complain.
})

export const i18n = createI18n({
  welcome: firstExample,
})

imo联合类型比枚举更易于使用。

相关问题