Пошук уроків, статей та іншого контенту
Додаємо необов’язкові та доступні лише для читання властивості до інтерфейсів.
За замовчуванням кожна властивість інтерфейсу є обов’язковою. Якщо об’єкт має тип цього інтерфейсу, він повинен містити всі описані властивості.
interface User {
name: string;
age: number;
}
const user: User = {
name: "Олена",
age: 28
};Якщо не вказати age, TypeScript повідомить про помилку:
interface User {
name: string;
age: number;
}
// Помилка: властивість age є обов’язковою
const user: User = {
name: "Олена"
};Щоб зробити властивість необов’язковою, після її назви потрібно додати знак питання ?.
interface User {
name: string;
age?: number;
}
const firstUser: User = {
name: "Олена",
age: 28
};
const secondUser: User = {
name: "Андрій"
};Тепер обидва об’єкти відповідають інтерфейсу User: властивість age може бути присутньою або відсутньою.
Перед використанням необов’язкової властивості варто перевірити, чи має вона значення.
interface User {
name: string;
age?: number;
}
function printUser(user: User): void {
if (user.age !== undefined) {
console.log(`${user.name}, вік: ${user.age}`);
} else {
console.log(`${user.name}, вік не вказано`);
}
}
printUser({ name: "Олена", age: 28 });
printUser({ name: "Андрій" });У цьому прикладі TypeScript знає, що всередині if властивість age має тип number.
Без перевірки TypeScript не дозволяє використовувати age як гарантоване число:
interface User {
name: string;
age?: number;
}
function getAgeInFiveYears(user: User): number {
// Помилка: age може бути undefined
return user.age + 5;
}Оскільки age необов’язкова, її тип фактично може бути number або undefined.
Властивість можна перевірити скороченим способом:
interface User {
name: string;
age?: number;
}
function printAge(user: User): void {
if (user.age) {
console.log(`Вік: ${user.age}`);
} else {
console.log("Вік не вказано");
}
}Однак перевірка if (user.age) не підходить у випадках, коли 0 є допустимим значенням. Надійніше явно перевіряти undefined:
if (user.age !== undefined) {
console.log(user.age);
}Для необов’язкової властивості можна використати значення за замовчуванням.
interface Settings {
theme?: string;
}
function showSettings(settings: Settings): void {
const theme = settings.theme ?? "light";
console.log(`Обрана тема: ${theme}`);
}
showSettings({ theme: "dark" });
showSettings({});Оператор ?? використовує значення праворуч, якщо значення ліворуч дорівнює null або undefined.
Іноді потрібно дозволити читати властивість, але заборонити змінювати її після створення об’єкта. Для цього використовується модифікатор readonly.
interface Product {
readonly id: number;
name: string;
price: number;
}
const product: Product = {
id: 101,
name: "Клавіатура",
price: 1200
};
console.log(product.id);Властивість id можна прочитати:
console.log(product.id);Але змінити її не можна:
// Помилка: властивість id доступна лише для читання
product.id = 102;Інші властивості без readonly можна змінювати:
product.name = "Механічна клавіатура";
product.price = 1500;readonly діє лише під час перевірки TypeScript. Це означає, що TypeScript не дозволяє таке присвоєння у вихідному коді, але сам модифікатор не є механізмом захисту даних під час виконання JavaScript.
readonly під час створення об’єктаВластивість readonly потрібно вказати під час створення об’єкта, якщо вона не має значення за замовчуванням.
interface Article {
readonly slug: string;
title: string;
}
const article: Article = {
slug: "typescript-basics",
title: "Основи TypeScript"
};Після створення об’єкта slug можна читати, але не можна переприсвоїти:
console.log(article.slug);
// Помилка: slug доступна лише для читання
article.slug = "new-slug";? і readonlyМодифікатори ? та readonly можна використовувати разом.
interface Profile {
readonly username: string;
readonly email?: string;
}
const profile: Profile = {
username: "olena"
};
console.log(profile.username);
console.log(profile.email);У цьому прикладі:
username є обов’язковою властивістю, яку не можна змінити;
email є необов’язковою властивістю, яку також не можна змінити після створення об’єкта.
interface Profile {
readonly username: string;
readonly email?: string;
}
const profile: Profile = {
username: "olena",
email: "olena@example.com"
};
// Помилка: username доступна лише для читання
profile.username = "new-name";
// Помилка: email доступна лише для читання
profile.email = "new@example.com";interface Book {
readonly isbn: string;
title: string;
author: string;
description?: string;
}
function printBook(book: Book): void {
console.log(`"${book.title}" — ${book.author}`);
console.log(`ISBN: ${book.isbn}`);
if (book.description !== undefined) {
console.log(`Опис: ${book.description}`);
} else {
console.log("Опис відсутній");
}
}
const book: Book = {
isbn: "978-617-000-000-1",
title: "Вивчаємо TypeScript",
author: "Ірина Коваль"
};
printBook(book);
book.title = "Вивчаємо TypeScript крок за кроком";
// Помилка, якщо розкоментувати:
// book.isbn = "978-617-000-000-2";Властивість description можна не вказувати, оскільки вона необов’язкова. Властивість isbn потрібно вказати, але після створення об’єкта її не можна змінити.
interface Task {
title: string;
completed: boolean;
}
// Помилка: відсутня властивість completed
const task: Task = {
title: "Вивчити інтерфейси"
};Якщо властивість справді може бути відсутньою, додайте ?:
interface Task {
title: string;
completed?: boolean;
}interface Task {
title: string;
priority?: number;
}
function printPriority(task: Task): void {
// Помилка: priority може бути undefined
console.log(task.priority + 1);
}Потрібно перевірити значення:
function printPriority(task: Task): void {
if (task.priority !== undefined) {
console.log(task.priority + 1);
}
}readonly-властивістьinterface Account {
readonly number: string;
owner: string;
}
const account: Account = {
number: "UA123456",
owner: "Олена"
};
// Помилка: number доступний лише для читання
account.number = "UA654321";readonly не означає, що властивість потрібно змінювати через спеціальний метод. Якщо значення має змінюватися, не додавайте до нього readonly.
readonly та константною змінноюconst забороняє переприсвоїти змінну, а readonly забороняє змінювати конкретну властивість об’єкта.
interface Point {
x: number;
readonly y: number;
}
const point: Point = {
x: 10,
y: 20
};
point.x = 15;
// point.y = 25; // Помилка
// point = { x: 0, y: 0 }; // Помилка через constconst стосується змінної point, а readonly — властивості y.
Знак ? робить властивість інтерфейсу необов’язковою.
Необов’язкова властивість може мати значення undefined.
Перед використанням необов’язкової властивості потрібно перевірити її значення або задати значення за замовчуванням.
Модифікатор readonly дозволяє читати властивість, але забороняє змінювати її після створення об’єкта.
? і readonly можна поєднувати.
const захищає посилання на змінну, а readonly — окрему властивість об’єкта.