Как мне добиться обратного отображения в TS с помощью enum

#javascript #typescript #enums

#javascript #typescript #перечисления

Вопрос:

итак, у меня есть перечисление со строковой индексацией

 enum MyEnum {
  str = "string"
}

console.log(MyEnum['str']); // string
console.log(MyEnum['string']); // undefined
  

Я хочу иметь возможность получить ключ через значение, т. Е.

 console.log(MyEnum['string']); // str
  

Однако это дает мне undefined . Есть ли способ добиться этого?

Вот моя попытка

 export enum EventType {
  JOB = "job"
}

type EventTypeKey = keyof typeof EventType;

const EVENT_TYPE_KEYS = new Map<EventType, EventTypeKey>(
  Object.entries(EventType).map(([key, value]: [EventTypeKey, EventType]) => [
    value,
    key
  ])
);

  

Однако компилятор TS выдал мне кучу загадочных ошибок компиляции

Ответ №1:

Вот некоторый код, который достигает того, что вы ищете:

 enum MyEnum {
  str = "string"
}

console.log(MyEnum['str']); // string
console.log((Object.keys(MyEnum)).find(key => (MyEnum as any)[key] == 'string')); // str
  

Комментарии:

1. Привет, спасибо за совет. вы знаете, почему моя попытка не проходит компилятор?

Ответ №2:

Я думаю, проблема в том, что (1) тип EventTypeKey и (2) Тип для new Map<EventTypeKey, EventTypeValue> и .map метода должны иметь одинаковый тип.

Попробуйте следующее

 enum EventType {
  JOB = "job"
}

type EventTypeKey = string;
type EventTypeValue =  string;

const EVENT_TYPE_KEYS = new Map<EventTypeKey, EventTypeValue>(
  Object.entries(EventType).map(([key, value]: [EventTypeKey, EventTypeValue]) => [
    value,
    key
  ])
);

console.log(EVENT_TYPE_KEYS.get("job"));
  

Комментарии:

1. привет, спасибо за ответ… Есть ли способ сделать EventTypeKey и EventTypeValue более конкретно типизированными?

Ответ №3:

используется @basarat, Object.keys потому что типом аргумента Object.keys является object, который подтверждает enum.

Итак, вы можете использовать Object.keys в enum.

Но тип аргумента Object.entries — это строго пара ключ-значение, которую enum не подтверждает.

Таким образом, вы не можете использовать Object.entries в enum.

Подробнее о enum читайте в typescript docs

По запросу op, вот его решение без ошибки типа

 const EVENT_TYPE_KEYS = new Map<EventType, EventTypeKey>(
    Object.keys(EventType).map((key: EventTypeKey) => [
        EventType[key],
        key
    ])
)
  

Комментарии:

1. Привет, спасибо, что указали на это! возможно ли немного изменить мое решение или переписать решение для передачи компилятору?

2. привет, спасибо за обновление. Однако я все еще вижу ошибку компилятора после вставки вашего решения. В нем говорится, что типы параметров «ключ» и «значение» несовместимы. Можете ли вы проверить еще раз? Спасибо!