Что значит опциональное поле в TypeScript
Что проверяют
Знаете ли, что знак вопроса меняет сразу две вещи: требование передавать свойство и его тип. И понимаете ли, что после сборки от этой пометки не остаётся ничего, проверка живёт только на этапе типизации.
Как отвечать
Опциональное поле объявляется знаком вопроса после имени и означает, что свойство можно не передавать, а его тип становится объединением с undefined.
interface User {
id: number;
email?: string; // string | undefined
}Отличие от email: string | undefined в том, что во втором случае ключ передать обязаны, пусть и со значением undefined. Различать эти два случая строго помогает флаг exactOptionalPropertyTypes: с ним в опциональное поле нельзя явно записать undefined, его можно только опустить.
Что сказать дальше:
- читают такое поле через проверку или необязательную цепочку
user.profile?.city, значение по умолчанию подставляют через??, а не через||, иначе пустая строка и ноль превратятся в дефолт; - после явной проверки TypeScript сам сузит тип и уберёт
undefined, отдельных приведений не нужно; - модальность меняют служебные типы:
Partial<T>делает все поля опциональными,Required<T>наоборот; - у параметров функций знак вопроса работает так же, но опциональный параметр обязан идти после обязательных.
Где спотыкаются
Ждут проверки во время работы. Типы стираются при сборке, поэтому данные из сети надо валидировать самим: ответ сервера легко может не содержать поле, помеченное в интерфейсе обязательным, и TypeScript об этом не узнает.
Второе: глушат ошибку восклицательным знаком. Запись user.email!.length убирает жалобу компилятора и оставляет падение в браузере, это обещание, а не проверка.
Третье: путают «поля нет» и «значение пустое». Поле count?: number со значением 0 существует, но проверка if (user.count) его пропустит. Проверять надо наличие: user.count !== undefined или "count" in user.