Пейджер

🌍 Всем привет! 👋

🌍 Всем привет! 👋

В дверь стучится TypeScript, ходят слухи что скоро перепишут на гошечку (не просто так ваш покорный слуга уже несколько недель учит go, ждите посты и по этому направлению).
Так вот, обещают ~х10 ⚡️ по приросту в скорости, поэтому TypeScript как никогда актуален и перспективен, учить надо абавязкова.
Сегодня говорим про Exhaustive Type Checking 😃.

😮‍💨 Мотивация

Заметил что многие не знают про Exhaustive Type Checking, и как следствие не используют, а делов то на пару лишних строчек. Это не какое-то кастомное, мудреное решение, нет, это есть прям в доке по ts.

🤔 Что за зверь эта рыба?

Это подход в TypeScript, который помогает избежать ложной полноты. Да-да, самые внимательные уже вспомнили что недавно я об этом писал. Это когда кажется, что обработал все варианты, а на деле пропустил какой-то важный кейс 😫.

📌 Давайте разберём на примере:

У нас есть статусы операций:

type StatusType = 'idle' | 'loading' | 'success' | 'error';

function handleStatus(status: StatusType) {
  if (status === 'idle') return 'Ожидаем действий пользователя ⏳';
  if (status === 'loading') return 'Данные загружаются... 🔄';
  if (status === 'success') return 'Данные успешно загружены! 🎉';
  if (status === 'error') return 'Ошибка при загрузке данных! ⚠️';

  throw new Error(`Необработанный статус: ${status}`);
}


Выглядит так, что каждый статус обработан и даже default-case есть (в роли ошибки) и можно не держать в голове имплементацию, а проcто тащить метод везде, где в этом есть необходимость.

А что если, завтра “Петя 🥸 удаленщик (он же домовой ), да простят меня все Пети, добавит новый тип статуса processing, но конечно же об этом никому не скажет.

В таком случае после деплоя вашей апки, вы успешно станете крашем 🤔.
Уже предвкушаю, что про себя, вы подумали, да у нас все четко, и Петь таких нет, и конвеншены налажены, но я вам не верю =), и предлагаю такое решение.

type Status = 'idle' | 'loading' | 'success' | 'error' | 'processing';

function handleStatus(status: Status) {
  if (status === 'idle') return 'Ожидаем действий пользователя ⏳';
  if (status === 'loading') return 'Данные загружаются... 🔄';
  if (status === 'success') return 'Данные успешно загружены! 🎉';
  if (status === 'error') return 'Ошибка при загрузке данных! ⚠️';

  const exhaustiveCheck: never = status;
  throw new Error(`Необработанный статус: ${exhaustiveCheck}`);
}


В тот момент, когда Петька добавил тип processing, TypeScript моментально укажет вам на ошибку, благодаря вот этой строчке:

const exhaustiveCheck: never = status;


Так происходит потому что нельзя переменной с типом never присвоить значение с другим типом string, number и тд.

Если забыли обработать какой-то статус — код просто не скомпилируется. Очень удобно!
Рабочий и наглядный пример искать тута.

🤔 Как же делать Exhaustive Checking правильно

✏️ Используйте строгие типы и никогда не доверяйте внешним данным без проверки.
✏️ Добавляйте обязательные проверки на все возможные состояния.
✏️ Пересматривайте код и добавляйте защитные условия (guards).

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

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