Модифікатор readonly в TypeScript, робить властивість об’єкту, класу, типу або інтерфейсу, доступною тільки для читання. readonly властивостям можна присвоювати значення лише під час ініціалізації об’єкта, або у конструкторі класу. Будь-яке інше присвоювання призведе до помилки компіляції.
Створення readonly властивості у TypeScript
Щоб створити властивість, доступну лише для читання, слід додати ключове слово readonly перед ім’ям властивості. Розглянемо приклади.
Об’єкт з властивістю readonly:
let product: { readonly name: string; price: number };
product = { name: 'iPhone 15', price: 1000 };
product.name = 'iPhone 15 Pro'; // Cannot assign to 'name' because it is a read-only property
product.price = 1100; // okreadonly властивість в інтерфейсі:
interface Product {
readonly name: string;
price: number;
}
let product: Product = { name: 'iPhone 15', price: 1000 };
product.name = 'iPhone 15 Pro'; // Cannot assign to 'name' because it is a read-only property
product.price = 1100; // okreadonly властивість в псевдонімі типу (type):
type Product = { readonly name: string; price: number };
let product: Product = { name: 'iPhone 15', price: 1000 };
product.name = 'iPhone 15 Pro'; // Cannot assign to 'name' because it is a read-only property
product.price = 1100; // okВ прикладах вище, властивість name позначено як readonly. Після присвоєння властивості name значення під час ініціалізації об’єкта, його вже не можна змінювати (при спробі зробити це, компілятор повідомляє про помилку – Cannot assign to ‘name’ because it is a read-only property).
readonly властивість у класі:
class Product {
readonly name: string;
price: number;
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
}
let product = new Product('iPhone 15', 1000);
product.name = 'iPhone 15 Pro'; // Cannot assign to 'name' because it is a read-only property
product.price = 1100; // okВ класі, присвоєне readonly властивості значення всередині функції constructor, не можна змінювати.
readonly властивість котра посилається на об’єкт
Як ми вже знаємо, не можна присвоювати нове значення властивості readonly. Але якщо цим значенням є об’єкт, властивості цього об’єкта можна змінювати.
Наведений нижче інтерфейс Person, має readonly властивість address, яка приймає в якості значення об’єкт, що реалізує інтерфейс Address:
interface Person {
name: string;
readonly address: Address;
}
interface Address {
city: string;
state: string;
}
let person: Person = { name: 'Jhon', address: { city: 'Belmont', state: 'Massachusetts' } };Ми не можемо призначити новий об’єкт властивості address, оскільки вона readonly:
person.address = { city: 'Dallas', state: 'Texas' };
// Cannot assign to 'address' because it is a read-only propertyПри цьому властивості самого об’єкта address можна змінювати:
person.address.city = 'Dallas'; // ok
person.address.state = 'Texas'; // okПри потребі заборонити можливість змінювати властивості об’єкта address, слід визначити як readonly властивості інтерфейсу Address:
interface Person {
name: string;
readonly address: Address;
}
interface Address {
readonly city: string;
readonly state: string;
}
let person: Person = { name: 'Jhon', address: { city: 'Belmont', state: 'Massachusetts' } };
person.address.city = 'Dallas'; // Cannot assign to 'city' because it is a read-only property
person.address.state = 'Texas'; // Cannot assign to 'state' because it is a read-only propertyВідмінність const та readonly
Може здатись, що ключове слово const у Typescript схоже на readonly, але це не так, вони мають деякі відмінності.
1. const – застосовується до змінних, readonly – до властивостей:
class Product {
name: string;
const price: number = 1000; // A class member cannot have the 'const' keyword
constructor(name: string, price: number) {
this.name = name;
this.price = price;
}
}Спроба визначити властивість price як const, призводить до помилки. Не можна використовувати let, var або const, в оголошенні властивостей. const використовується для створення змінних:
const product = new Product('iPhone 15', 1000);
product = new Product('iPhone 15 Pro', 2000); // Cannot assign to 'product' because it is a constant
product.price = 2000; //okВ прикладі вище, ключове слово const використовується для створення змінної константи product. Ми не можемо призначити нове значення змінній product, але можемо зробити зміни в самому об’єкті, на який вона посилається.
В той же час, ми не можемо оголосити змінну як readonly:
let readonly product = new Product('iPhone 15', 1000); // ',' expected2. const – перевіряється під час виконання, readonly – перевіряється під час компіляції
const – це конструкція JavaScript. Отже, існує під час виконання.
Властивість readonly є специфічною для TypeScript, та використовується для перевірки заборонених присвоєнь значень властивостям, під час компіляції. readonly прибирається в коді JavaScript після компіляції, та не існує на час виконання.
Як зробити властивості вже існуючого типу readonly
Спеціальний тип Readonly створює новий тип на основі вже існуючого типу, при цьому всі властивості нового типу встановлюються як readonly:
interface Product {
name: string;
price: number;
}
let product: Readonly<Product> = { name: 'iPhone 15', price: 1000 };
product.name = 'iPhone 15 Pro'; // Cannot assign to 'name' because it is a read-only property
product.price = 1100; // Cannot assign to 'price' because it is a read-only propertyУ цьому прикладі, об’єкт product створюється на основі інтерфейсу Product, перетвореного за допомогою Readonly. Як результат, властивості product після ініціалізації доступні лише для читання.