Що робить Partial<T>?
1. Що робить Partial<T>
Partial<T>робить усі властивості типуTнеобов'язковими (optional).
Це означає, що всі поля інтерфейсу T, які раніше були обов'язковими,
стають опціональними (?).
Приклад
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial<User>;Тепер PartialUser еквівалентний:
{
id?: number;
name?: string;
email?: string;
}Усі властивості стали необов'язковими (
?).
2. Як Partial<T> змінює властивості інтерфейсу
Він проходить по кожному ключу інтерфейсу T
і робить властивість опціональною через mapped type:
type Partial<T> = {
[P in keyof T]?: T[P];
};Це вбудована реалізація
Partialвсередині TypeScript.
Приклад використання
interface Config {
port: number;
host: string;
}
const cfg: Partial<Config> = {
port: 8080, // можна вказати одне поле
};Все працює, навіть якщо вказано лише
port.
3. Що робить Partial<T> з обов'язковими властивостями
Partial<T> скасовує обов'язковість усіх полів,
навіть якщо вони були обов'язковими (required) у вихідному типі.
Приклад
interface Settings {
theme: string;
notifications: boolean;
}
type PartialSettings = Partial<Settings>;
const s1: PartialSettings = {}; // можна порожній об'єкт
const s2: PartialSettings = { theme: "dark" }; // можна частковоНавіть обов'язкове поле
themeтепер необов'язкове.
4. Чи можна застосувати Partial до вкладених об'єктів?
Чудове запитання - і це ключовий момент, де багато хто плутається.
За замовчуванням
Partial<T>працює лише на першому рівні.
Тобто вкладені об'єкти не стають опціональними всередині себе.
Приклад
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:
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};Приклад з DeepPartial
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> |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.