Как отобразить перечисления на основе идентичных имен ключей? - PullRequest
0 голосов
/ 21 апреля 2019

У меня есть два перечисления с одинаковыми именами ключей, и я хочу иметь возможность использовать значение из одного перечисления для получения значения из второго перечисления.

Примером может быть преобразование ошибок сервера в ошибки клиента в приложении:

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

1 Ответ

2 голосов
/ 21 апреля 2019

Поскольку ключи одинаковы в обоих перечислениях, вы можете просто индексировать, используя один и тот же ключ. Перечисления являются объектами во время выполнения, поэтому вы можете искать одно перечисление, чтобы найти значения и индексировать в другое перечисление:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...