Утверждение типа парсером не является. Внешний ответ приходит байтами, и пока его никто не проверил, ничто в нём не говорит, какой это вариант.
Сначала декодирование текста и разбор JSON, у каждого свой путь отказа. Результат разбора должен попадать в проверку как unknown.
Поддерживаются два ответа. Метка ready с массивом строк items или метка failed со строкой message. Проверка во время выполнения должна убедиться в трёх вещах. Значение является объектом, метка нам известна, а данные для этой метки имеют нужную форму. Объект с ready без items неполон. Объект с waiting несёт метку, которой нет в нашем типе. Приведение через as к объединению не исправит ни то, ни другое.
После успешной проверки декодер возвращает размеченное объединение. Ветка с проверкой на ready сужает значение, и элементами можно пользоваться. Исчерпывающая проверка через never покажет необработанный вариант в объявленной модели. Для сопровождения это полезно, но в байты ответа она не смотрит.
С отклонённым вводом нужно что-то решить. Сообщить об ошибке декодирования или сознательно смоделировать неизвестный ответ как ещё один вариант. Тихое приведение к принятому объединению этот выбор пропускает.
Держите проверку во время выполнения рядом с местом, где строится типизированное значение. А вычисления в каждом обработчике проверяйте отдельно, ведь покрытая ветка всё равно может посчитать неправильно.