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 — локальная установка не требуется.
Все уроки этого курса
- DeepPartial и DeepReadonly
- Утилиты Flatten и UnwrapPromise
- TupleToUnion и UnionToIntersection
- Публикация библиотеки утилит типов