【问题标题】:How to map between enums based on identical key names?如何基于相同的键名在枚举之间映射?
【发布时间】:2019-04-21 14:13:13
【问题描述】:

我有两个具有相同键名的枚举,我希望能够使用一个枚举中的值从第二个枚举中获取值。

例如,将服务器错误转换为应用程序中的客户端错误:

enum serverErrors {
  first = "server error 1",
  second = "server error 2",
  third = "server error 3"
}

enum clientErrors {
  first = "client error 1",
  second = "client error 2",
  third = "client error 3"
}

目前我们正在使用这样的函数:

function translate(s: string) {
    switch (s) {
        case serverErrors.first:
            return clientErrors.first;
            /// ...
    }
}

我希望能够执行与上述类似的操作,而无需手动指定每个键应转换为什么 - 它应该根据键的名称发生。

我试过了:

type translator = {
  // Error: Type 'P' cannot be used to index type 'clientErrors'.
  [P in keyof typeof serverErrors]: clientErrors[P];
};

虽然我不确定如何从上面获取字符串值,即使它确实有效。

我希望这段代码可以工作:

const serverError = serverErrors.first;
const clientError = enumTranslator(serverError); // === clientError.first

【问题讨论】:

    标签: javascript typescript enums


    【解决方案1】:

    由于两个枚举中的键相同,因此您可以使用相同的键进行索引。枚举是运行时的对象,因此您可以搜索一个枚举以查找值并索引到另一个枚举:

    enum serverErrors {
        first = "server error 1",
        second = "server error 2",
        third = "server error 3"
    }
    
    enum clientErrors {
        first = "client error 1",
        second = "client error 2",
        third = "client error 3"
    }
    
    function translate<
        TSource extends Record<keyof TSource, string>,
        TTarget extends Record<keyof TSource, string>>(source: TSource, target: TTarget, s: string) {
    
        for (const key in source) {
            if (source[key] === s) {
                return target[key];
            }
        }
        throw new Error("Member not found");
    }
    
    let a = translate(serverErrors, clientErrors, serverErrors.first);
    console.log(a);
    

    【讨论】:

    • 太好了,扩展 Record&lt;keyof... 甚至可以确保它们有一组匹配的键,所以不会出错。
    • @RanLottem 是的,这就是想法,尽量让它在编译时尽可能安全:)
    猜你喜欢
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 2016-12-13
    • 2021-08-30
    • 2012-09-08
    • 1970-01-01
    相关资源
    最近更新 更多