Выбор ответа Middle Объединения и сужение обновлено

Неверный type guard

Вопрос

Что произойдёт?

function isString(x: unknown): x is string {
  return typeof x === 'number';
}
const v: unknown = 5;
if (isString(v)) console.log(v.toUpperCase());

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Компилируется, в рантайме TypeError: toUpperCase is not a function. Компилятор не проверяет, что тело type guard действительно соответствует предикату x is string.

Варианты ответа

  1. Ошибка компиляции: тело guard не соответствует x is string
  2. Компилируется, а в рантайме ничего не выводится и ошибок нет
  3. Компилируется, в рантайме TypeError: toUpperCase is not a functionправильный ответ
  4. Компилируется и выводит '5': число приведётся к строке само

Разбор

Компилятор не проверяет, что тело type guard действительно соответствует предикату x is string. Здесь guard возвращает true для числа, компилятор верит и разрешает v.toUpperCase(). В рантайме у числа такого метода нет, получаем TypeError.

«Ничего не выводится» было бы при правильном guard. Строку '5' число само не превратит. Поэтому guard'ы покрывают тестами и держат максимально простыми.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.