Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить Partial<T>?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Partial<T>** робить усі властивості типу `T` необов'язковими (`optional`), проходячи через кожен ключ типу і додаючи `?` до нього через mapped type `[P in keyof T]?: T[P]`. **Ключове:** за замовчуванням Partial працює лише на першому рівні - вкладені об'єкти не стають опціональними всередині себе, для цього потрібен власний рекурсивний тип `DeepPartial`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що робить `Partial<T>` > `Partial<T>` робить **усі властивості типу** `T` **необов'язковими** (`optional`). Це означає, що всі поля інтерфейсу `T`, які раніше були обов'язковими, стають **опціональними (**`?`**)**. --- ### Приклад ```javascript interface User { id: number; name: string; email: string; } type PartialUser = Partial<User>; ``` Тепер `PartialUser` еквівалентний: ```javascript { id?: number; name?: string; email?: string; } ``` > Усі властивості стали необов'язковими (`?`). --- ## 2. Як `Partial<T>` змінює властивості інтерфейсу Він **проходить по кожному ключу** інтерфейсу `T` і робить властивість опціональною через *mapped type*: ```javascript type Partial<T> = { [P in keyof T]?: T[P]; }; ``` > Це вбудована реалізація `Partial` всередині TypeScript. --- ### Приклад використання ```javascript interface Config { port: number; host: string; } const cfg: Partial<Config> = { port: 8080, // можна вказати одне поле }; ``` > Все працює, навіть якщо вказано лише `port`. --- ## 3. Що робить `Partial<T>` з обов'язковими властивостями `Partial<T>` **скасовує обов'язковість** усіх полів, навіть якщо вони були обов'язковими (`required`) у вихідному типі. --- ### Приклад ```javascript interface Settings { theme: string; notifications: boolean; } type PartialSettings = Partial<Settings>; const s1: PartialSettings = {}; // можна порожній об'єкт const s2: PartialSettings = { theme: "dark" }; // можна частково ``` > Навіть обов'язкове поле `theme` тепер необов'язкове. --- ## 4. Чи можна застосувати `Partial` до вкладених об'єктів? Чудове запитання - і це **ключовий момент**, де багато хто плутається. > За замовчуванням `Partial<T>` працює **лише на першому рівні**. Тобто **вкладені об'єкти не стають опціональними всередині себе**. --- ### Приклад ```javascript interface Profile { id: number; info: { name: string; age: number; }; } type PartialProfile = Partial<Profile>; const p: PartialProfile = { info: {}, // Помилка: очікуються name та age }; ``` > TypeScript все ще вимагає `name` і `age`, > тому що `Partial` зробив опціональним лише саме поле `info`, > але не його внутрішні властивості. --- ## 5. Як зробити **глибокий Partial** (рекурсивний) Якщо потрібно, щоб **вкладені властивості теж стали опціональними**, можна створити власний тип **DeepPartial**: ```javascript type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]; }; ``` --- ### Приклад з DeepPartial ```javascript interface Profile { id: number; info: { name: string; age: number; }; } const user: DeepPartial<Profile> = { info: { name: "Tim", // можна вказати лише одне поле }, }; ``` > Тепер вкладені поля теж необов'язкові. --- ## 6. Коли використовують `Partial<T>` | Сценарій | Приклад | |---|---| | Оновлення даних (патч) | `updateUser(id: number, data: Partial<User>)` | | Конфігурації та налаштування | `Partial<Config>` дозволяє задати лише потрібні поля | | При створенні mock-об'єктів у тестах | можна не вказувати всі поля інтерфейсу | | У формах та DTO | коли значення надходять частково | --- ## Підсумок | Питання | Відповідь | |---|---| | Що робить `Partial<T>` | Робить усі властивості типу `T` опціональними | | Як змінює інтерфейс | Додає `?` до всіх властивостей (`[P in keyof T]?: T[P]`) | | Що відбувається з обов'язковими властивостями | Вони стають необов'язковими | | Чи працює з вкладеними об'єктами | Ні, лише поверхнево | | Як зробити вкладені теж опціональними | Використати кастомний `DeepPartial<T>` |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.