0Pricing
TypeScript Academy · Урок

DeepPartial и DeepReadonly

Создавайте рекурсивные версии Partial и Readonly

«DeepPartial и DeepReadonly» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.

Зачем нужны глубокие вспомогательные типы

Встроенные Partial и Readonly применяются только на одном уровне вложенности. Для вложенных объектов нужны рекурсивные версии.

interface Config {
  db: { host: string; port: number };
  app: { name: string };
}
type Shallow = Partial<Config>;
// Shallow.db is still required — only top level is optional

Реализация DeepPartial

Рекурсивно перебирайте свойства объекта, делая каждое из них необязательным и рекурсивно применяя DeepPartial, если значение свойства является объектом.

type DeepPartial<T> = T extends object
  ? { [K in keyof T]?: DeepPartial<T[K]> }
  : T;

DeepPartial в действии

Примените DeepPartial к вложенному типу конфигурации и увидите, что все уровни становятся необязательными.

type PartialConfig = DeepPartial<Config>;
// PartialConfig.db?: { host?: string; port?: number }

const c: PartialConfig = { db: { host: "localhost" } };
// No error — all other fields are optional

Реализация DeepReadonly

Сделайте каждое свойство на любой глубине readonly, рекурсивно проходя по вложенным типам объектов.

type DeepReadonly<T> = T extends object
  ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
  : T;

DeepReadonly в действии

Глубоко замороженную конфигурацию нельзя изменить ни на одном уровне.

type ReadonlyConfig = DeepReadonly<Config>;
const cfg: ReadonlyConfig = { db: { host: "localhost", port: 5432 }, app: { name: "my-app" } };
// cfg.db.port = 3000; // Error: readonly

Обработка массивов в глубоких типах

Массивы требуют особой обработки: рекурсивно преобразуйте типы элементов, а не рассматривайте массивы как обычные объекты.

type DeepPartial<T> =
  T extends (infer U)[]
    ? DeepPartial<U>[]
    : T extends object
      ? { [K in keyof T]?: DeepPartial<T[K]> }
      : T;

Обработка примитивов

Базовый случай рекурсии должен возвращать примитивные типы без изменений, а не оборачивать их в отображаемый тип объекта.

type DeepReadonly<T> =
  T extends string | number | boolean | null | undefined ? T
  : T extends (infer U)[] ? ReadonlyArray<DeepReadonly<U>>
  : { readonly [K in keyof T]: DeepReadonly<T[K]> };

Объединение DeepPartial и DeepReadonly

Вы можете объединить их, чтобы создать глубоко частичный тип только для чтения для безопасного применения исправлений к конфигурации.

type SafePatch<T> = DeepReadonly<DeepPartial<T>>;

Вопросы производительности

Рекурсивные типы для очень больших объектов могут замедлить проверку типов TypeScript. Для кода, критичного к производительности, рассмотрите ограничение глубины или ленивое вычисление.

// For very deep schemas, consider using Zod or io-ts
// which provide runtime + compile-time deep typing

Практическое применение: исправления состояния React

DeepPartial идеально подходит для функций исправления состояния, принимающих только изменённую часть большого объекта состояния.

function patch<T>(state: T, changes: DeepPartial<T>): T {
  return { ...state, ...changes } as T;
}

Итоги: глубокие вспомогательные типы

DeepPartial и DeepReadonly — это рекурсивные отображаемые типы, применяющие свой модификатор к каждому уровню вложенного объекта. Обрабатывайте массивы отдельно и используйте базовые случаи для примитивов.

Быстрая проверка

Каков правильный базовый случай рекурсии для DeepPartial?

Что Вы узнали

Вы реализовали DeepPartial и DeepReadonly с помощью рекурсивных отображаемых типов. Обрабатывайте массивы как особый случай и всегда возвращайте примитивы без изменений в базовом случае.

Часто задаваемые вопросы

Урок «DeepPartial и DeepReadonly» бесплатный?

Да — полный текст урока «DeepPartial и DeepReadonly» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.

Чему я научусь в уроке «DeepPartial и DeepReadonly»?

Создавайте рекурсивные версии Partial и Readonly Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать TypeScript Academy?

Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «DeepPartial и DeepReadonly»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке TypeScript Academy?

Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. DeepPartial и DeepReadonly
  2. Утилиты Flatten и UnwrapPromise
  3. TupleToUnion и UnionToIntersection
  4. Публикация библиотеки утилит типов
← Назад к TypeScript Academy