Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить Readonly<T>?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`Readonly<T>` робить **усі властивості об'єкта доступними лише для читання** - тобто їх не можна змінювати, перевизначати чи видаляти після створення об'єкта. **Ключове:** `Readonly<T>` захищає внутрішні поля об'єкта на рівні системи типів, тоді як `const` захищає лише саму змінну (посилання), а не її вміст.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що робить `Readonly<T>` > `Readonly<T>` робить **усі властивості об'єкта доступними лише для читання** - > тобто їх **не можна змінювати, перевизначати чи видаляти** після створення об'єкта. --- ### Приклад ```javascript interface User { id: number; name: string; } const user: Readonly<User> = { id: 1, name: "Tim", }; user.name = "Max"; // Помилка: не можна змінити властивість "name" ``` > Можна читати `user.name`, але не можна змінювати. > TypeScript видає помилку ще **на етапі компіляції**, до запуску коду. --- ## 2. Як `Readonly<T>` влаштований усередині Тип `Readonly<T>` реалізований через **mapped type**: ```javascript type Readonly<T> = { readonly [P in keyof T]: T[P]; }; ``` Пояснення: - `keyof T` - бере всі ключі типу `T`; - `readonly` - додає модифікатор "лише для читання"; - `T[P]` - зберігає оригінальний тип властивості. --- ## 3. Чим `Readonly<T>` відрізняється від `const` Чудове питання - їх часто плутають. Дивись відмінності нижче. | Особливість | `Readonly<T>` | `const` | | --- | --- | --- | | Застосовується до | типу (об'єкта, інтерфейсу, generic) | змінної | | Перевіряється | на рівні **властивостей** | на рівні **посилання** | | Захищає | внутрішні поля об'єкта | лише саму змінну | | Місце дії | у системі типів (TypeScript) | у рантаймі (JavaScript) | --- ### Приклад порівняння ```javascript const user = { id: 1, name: "Tim" }; user.name = "Max"; // Дозволено! ``` > `const` не дозволяє **перепризначити змінну** `user = ...`, > але змінювати поля об'єкта можна. --- А ось з `Readonly<T>`: ```javascript const user: Readonly<{ id: number; name: string }> = { id: 1, name: "Tim", }; user.name = "Max"; // Помилка - властивість readonly ``` > `Readonly<T>` захищає **вміст**, > а `const` - **саму змінну** (посилання). --- ### Комбіноване використання Можна поєднати `const` і `Readonly` для повного захисту: ```javascript const user: Readonly<{ id: number; name: string }> = { id: 1, name: "Tim", }; ``` > Тепер: > > - `user` не можна перепризначити (через `const`); > - `user.name` не можна змінити (через `Readonly`). --- ## 4. Що станеться, якщо спробувати змінити властивість `Readonly<T>` TypeScript **заблокує зміну на етапі компіляції** - видасть помилку на кшталт: ```javascript Cannot assign to 'property' because it is a read-only property. ``` --- ### Приклад ```javascript interface Config { port: number; host: string; } const cfg: Readonly<Config> = { port: 8080, host: "localhost", }; cfg.port = 3000; // Помилка: властивість лише для читання ``` > У скомпільованому JavaScript це **не блокується на рівні виконання** > (TypeScript видаляє типи), > але IDE і компілятор **не дозволять тобі допустити помилку в коді**. --- ## 5. Readonly для масивів Можна зробити масив незмінним: ```javascript const nums: ReadonlyArray<number> = [1, 2, 3]; nums.push(4); // Помилка nums[0] = 10; // Помилка ``` > Можна лише читати елементи, але не змінювати структуру. --- ## 6. Глибока незмінність (Deep Readonly) Звичайний `Readonly<T>` захищає **лише верхній рівень**. Вкладені об'єкти **залишаються змінюваними**. --- ### Приклад: ```javascript interface User { id: number; profile: { name: string; city: string; }; } const u: Readonly<User> = { id: 1, profile: { name: "Tim", city: "Kyiv" }, }; u.profile.city = "Paris"; // Дозволено! (Readonly лише верхній рівень) ``` --- Щоб заборонити зміни **всередині вкладених об'єктів**, використай **DeepReadonly**: ```javascript type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P]; }; const deepUser: DeepReadonly<User> = { id: 1, profile: { name: "Tim", city: "Kyiv" }, }; deepUser.profile.city = "Paris"; // Помилка ``` --- ## Підсумок | Питання | Відповідь | | --- | --- | | Що робить `Readonly<T>` | Робить усі властивості типу лише для читання (`readonly`) | | Чим відрізняється від `const` | `Readonly` захищає **внутрішні поля**, `const` - **саму змінну** | | Що станеться при спробі змінити | TypeScript видасть помилку "Cannot assign to '...' because it is a read-only property" | | Чи працює глибоко | Ні, лише верхній рівень (для глибокого захисту - `DeepReadonly<T>`) |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.