Опциональные и readonly свойства
Тонкая настройка свойств: что может отсутствовать и что нельзя менять.
Модификатор
?делает свойство необязательным,readonly— запрещает его изменять после создания.
Опциональные свойства
Не у всех объектов заполнены все поля. Необязательное свойство помечают ? — его можно не указывать:
interface User {
name: string;
age: number;
phone?: string; // может быть, а может не быть
}
const a: User = { name: "Аня", age: 30 }; // ок, без phone
const b: User = { name: "Боря", age: 25, phone: "555" }; // тоже ок
Тип такого свойства внутри — string | undefined. Поэтому перед использованием его нужно проверить, иначе компилятор не пропустит:
function callUser(u: User) {
// u.phone.length; // Ошибка: 'u.phone' is possibly 'undefined'.
if (u.phone) {
console.log("Звоним на " + u.phone);
}
}
Это защищает от обращения к отсутствующему полю — частого источника ошибок при работе с данными API, где поля приходят не всегда.
readonly свойства
Модификатор readonly делает свойство неизменяемым: его задают при создании, но переписать потом нельзя.
interface Account {
readonly id: number; // выдаётся один раз
balance: number; // меняется
}
const acc: Account = { id: 1, balance: 100 };
acc.balance = 150; // ок
acc.id = 2; // Ошибка: Cannot assign to 'id' because it is a read-only property.
Это защита на этапе компиляции: случайно изменить идентификатор, дату создания или другое неизменяемое поле не получится. Баг «кто-то перезаписал id» становится невозможен.
Важно: readonly — только для проверки типов
Помните: readonly существует лишь во время компиляции. В готовом JavaScript никакой защиты не остаётся — это не Object.freeze. Польза в том, что компилятор не даст написать изменяющий код, и ошибка не доедет до рантайма.
readonly-массивы
Массив тоже можно сделать неизменяемым — тогда у него пропадают мутирующие методы (push, pop):
const days: readonly string[] = ["Пн", "Вт", "Ср"];
days.push("Чт"); // Ошибка: Property 'push' does not exist on type 'readonly string[]'.
Это удобно для констант и данных, которые не должны меняться после инициализации.
Памятка
| Модификатор | Смысл |
phone?: string | свойства может не быть; тип string | undefined |
readonly id: number | задаётся при создании, менять нельзя |
readonly string[] | массив без мутирующих методов |
Итог
?делает свойство необязательным; перед использованием его проверяют наundefined.readonlyзапрещает изменять свойство после создания — защита от случайной перезаписи.- Оба модификатора работают только на этапе компиляции, без накладных расходов в рантайме.