Пейджер

🌍 Привет мир! 👋

🌍 Привет мир! 👋

Cегодня тема которая частенько является "холиварной" в командах. Попробуем еще раз разобраться что же лучше "enum" или "as const". И может быть именно показ подводных камней от использования Enum, cделают перевес.

🚀 Мотивация

Работа в команде, это набор ваших внутренних соглашений. Идеально когда они задокументированы, но так к сожалению не всегда, иногда самым главным документом является ваш код, где новичку практически на любой вопрос будет один ответ - “делай как везде и будет классно”. Вот и нам нужно решить, как будет везде? Enum или все-таки as const .

Какую задачу решает enum и as const

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

const vegetableTypes = {
  CARROTS: "carrots",
  CABBAGE: "cabbage",
} as const;

enum vegetableTypes {
  CARROTS = "carrots",
  CABBAGE = "cabbage",
};


👇 Типы enum
Enum можно разделить на 3 типа:

📌 Числовые

enum vegetableTypes {
  CARROTS = 0,
};

📌 Cтроковые

enum vegetableTypes {
  CARROTS = "carrots",
};

📌 Inferred (когда typescript сам предполагает value)

enum vegetableTypes {
  CARROTS, // Inferred as 0
};


🗿 Недостатки при использовании enum

Между поведением строковых и числовых enums есть отличие, очень важное. Часто необходимо для решения какой-то задачи, перебрать ключи enum, и в этот момент может всплыть “pitfall”.

⁉️ Как думаете что будет выведено в логе?

(1)
enum vegetableTypes {
  CARROTS = 0,
  CABBAGE = 1,
};

console.log(Object.keys(vegetableTypes));

(2)
enum vegetableTypes {
  CARROTS = "carrots",
  CABBAGE = "cabbage",
};

console.log(Object.keys(vegetableTypes));


1. ["0", "1", "CARROTS", "CABBAGE"] 2. ["CARROTS", "CABBAGE"]

☝️ Как видно из примеров, в числовых enum вывод получается как из ключей так и из значений.

‼️ Следующая проблема может вызывать раздражение при проверке типов:

Далее пример с двумя типами enum и функцией которая в качестве аргумента принимает тип “овоща”.

Как думаете будут ли ошибки от проверки типов?

enum vegetableTypes1 {
  CARROTS = 0,
};

enum vegetableTypes2 {
  CABBAGE = "cabbage",
};

const getVegetable = (vegetable: vegetableTypes) => {
  return vegetable
};

* getVegetable(vegetableTypes1.СARROTS)
* getVegetable(0)
* getVegetable(vegetableTypes2.CABBAGE)
* getVegetable("cabbage")


1) ✅ 2) ✅ 3) ✅ 4) ❌ Argument of type '"cabbage"' is not assignable to parameter of type 'vegetableTypes2'.

📝 Как итог, снова отличие в поведении строковых и числовых enum. В функции, аргумент которой является строковым enum, не может принимать просто строку, даже если она полностью идентична значению enum.

💡 Еще интересный момент заключается в том, что значения одного enum, который равен второму, не могут использоваться в качестве аргументов функции, TypeScript “жестко” проверяет тип на входе.

enum vegetableTypes1 {
  CABBAGE = "cabbage",
};

enum vegetableTypes2 {
  CABBAGE = "cabbage",
};

const getVegetable = (vegetable: vegetableTypes1) => {
  return vegetable
};

getVegetable(vegetableTypes2.CABBAGE)

❌ Ошибка: Argument of type 'typeof vegetableTypes2' is not assignable to parameter of type 'vegetableTypes1'.

Ну и в общем, если посмотреть на issues которые созданы в репозитории TypeScript, часто упоминается enum.

📌 Итог

Я выбрал “as const” и убрал лишнюю когнитивную нагрузку из своей головы, может быть позже я пожалею, но пока не вижу причин для этого.

💬 Делитесь своим мнением в комментариях👇! Если вам понравилась статья, не забудьте поставить лайк! 👍

#TYPESCRIPT
Медиа 1
Хотите больше таких постов?
Подпишитесь на канал и читайте продолжение в Telegram.
Подписаться на @ivanchikovitclub Открыть пост в Telegram