Видеоуроки, интерактивный редактор и сохранение прогресса — бесплатно, сразу после входа.
ВойтиСоздать аккаунт — бесплатноЗакончили урок?
Войдите, чтобы отмечать прогресс
После проверки result.status === "success" тип в теле if сужен до Success, и поле data доступно. Ниже остаётся единственный вариант Failure со своим message. Приведений типов не нужно нигде.
Если бы поле было объявлено как status: string, сужение не сработало бы:
Компилятор сопоставляет варианты именно по значению литерала, поэтому дискриминант должен быть литеральным типом (обычно строковым, но подойдут число или булево).
Проверка по уникальному полю работает, но с ростом числа вариантов становится хрупкой: свойства пересекаются, проверок всё больше, легко пропустить ветку. Дискриминант остаётся одним и тем же независимо от того, сколько вариантов в union, и добавление нового не ломает существующие проверки.
Главный бонус приёма проявляется через switch:
Пока обработаны все варианты, в default попадает тип never, и присваивание проходит. Стоит добавить в Result третий вариант, например { status: "loading" }, и компилятор подсветит эту строку: обработчик неполный. Так система типов напоминает дописать код там, где о нём легко забыть.
Дискриминированные объединения повсюду в реальном коде: состояния загрузки (idle, loading, success, error), ответы API, действия редьюсера в useReducer (там дискриминант это поле type). Умение читать и писать такие типы это, пожалуй, самое практичное из всего курса.