【问题标题】:typescript: How to define type as any part of enum?打字稿:如何将类型定义为枚举的任何部分?
【发布时间】:2021-07-08 15:00:43
【问题描述】:

我正在尝试使用打字稿创建翻译模块。

我想将语言定义为创建文本函数的枚举参数,如下所示:


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,

})

但我的问题是,因为语言作为参数传递给打字稿函数并且该函数推断类型,所以打字稿不会引起任何担忧。我可以用不存在的语言创建文本,它会通过它,比如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
    }
}

所以代码正在运行并做它需要做的任何事情,但我正在失去类型控制。

我更喜欢将我的枚举值小写,所以这也是一个问题。如果这是解决方案,那么我会接受它,但是如果有任何方法可以传递枚举参数并按其值运行,那就太好了。

【问题讨论】:

  • this 是否可以将语言名称限制为传入的内容?如果没有,请详细说明缺少的内容。否则我可以在有机会的时候写一个答案。

标签: javascript reactjs typescript generics enums


【解决方案1】:

您可以让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 联合类型比枚举使用起来更舒服。

【讨论】:

  • 谢谢!它有效,但我仍然更喜欢枚举。 @jcalz 评论也很有效。感谢您的努力!
  • 不要忘记将问题标记为已回答 ;)
猜你喜欢
  • 2020-04-14
  • 2021-06-02
  • 1970-01-01
  • 2021-07-08
  • 2017-03-09
  • 2018-11-06
  • 2020-12-24
  • 2019-07-09
  • 2022-06-11
相关资源
最近更新 更多