Что такое Partial в TypeScript

Ответ

Partial<T> — это утилитарный тип в TypeScript, который делает все свойства типа T необязательными. Это полезно, когда нужно создать объект с частичными значениями, например, для обновления или инициализации.

Пример:

interface User {
  id: number;
  name: string;
  age: number;
}

const updateUser: Partial<User> = {
  name: "John" // можно указать только нужные поля
};

Особенности:

  • Все свойства становятся ?:
  • Полезен для DTO, патчей, дефолтных значений
  • Не влияет на методы, только на свойства

Аналог ручного написания:

type ManualPartial<T> = {
  [P in keyof T]?: T[P];
};

Осторожно: Partial не проверяет, что хотя бы одно свойство будет задано. Для строгой проверки используйте Required<Partial<T>> или кастомные решения.

Ответ 18+ 🔞

Да ты посмотри, что эти умники в TypeScript выдумали! Partial<T> — это ж как взять любой интерфейс и сказать ему: «Знаешь что, дружок? Расслабься. Сегодня все твои поля — по желанию. Хочешь — заполняй, не хочешь — иди нахуй».

Ну серьёзно. Вот есть у тебя, допустим, пользователь, строгий такой:

interface User {
  id: number;
  name: string;
  age: number;
}

И ты такой: «О, надо бы обновить только имя!». Так нахуй ты будешь новый объект городить, где все поля обязательные? Правильно, никак. Берёшь Partial<User> и делаешь:

const updateUser: Partial<User> = {
  name: "Васян" // а `id` и `age` — пусть идут лесом, они теперь optional!
};

И всё, блядь! TypeScript не орёт на тебя, что ты мудак и не заполнил всё. Красота.

Что он делает, этот хитрый ёж? Буквально берёт все ключи из T и каждому из них прикручивает вопросительный знак. Всё. Вся магия. Если бы мы его писали руками, это выглядело бы так:

type ManualPartial<T> = {
  [P in keyof T]?: T[P]; // Смотри-ка, вопросик появился!
};

Где это полезно? Да везде, где работаешь с кусками данных! Отправка PATCH-запроса на API, создание объекта с дефолтными значениями (смешиваешь дефолты с тем, что пришло), всякие DTO для обновления — просто пиздец как удобно.

Но есть подвох, ёпта! Partial — он добрый до безобразия. Он не требует указать хоть что-нибудь. Вот такой тип — это валидный Partial<User>:

const emptyUpdate: Partial<User> = {}; // Ни хуя не указал!

Иногда это ок, а иногда — нет. Если тебе критично, чтобы в объекте было хотя бы одно поле из списка, то Partial один не справится. Придёшь к нему, а он такой: «Сам разбирайся, я только вопросики ставлю». Для строгих случаев надо или Required<Partial<T>> (что, по сути, вернёт тебя к исходному T, лол), или кастомные типы-комбинаторы писать. Но это уже другая история, про которую можно охуеть.

Короче, Partial<T> — это как разрешение на халяву. Пользуй, но не обосрись.