Разбор задачи: пишем свой
Встроенный тип
Пишем свой рекурсивный тип!
Что тут происходит и какие фишки TS задействованы:
1) Mapped Types (
2) Conditional Types (
3) Record - безопасная проверка на объектную структуру (в отличие от
4) Recursive Types (
💻 Пример использования:
DeepPartial в TypeScript 🧠Встроенный тип
Partial делает необязательными только ключи верхнего уровня. А что делать, если у нас сложная вложенная структура и мы хотим сделать optional абсолютно все поля на всех уровнях вложенности?Пишем свой рекурсивный тип!
type DeepPartial<T> = {
[key in keyof T]?: T[key] extends Record<string, unknown>
? DeepPartial<T[key]>
: T[key]
}Что тут происходит и какие фишки TS задействованы:
1) Mapped Types (
[key in keyof T]?: ...) - проходим по всем ключам объекта и делаем их необязательными с помощью ?.2) Conditional Types (
T[key] extends ... ? A : B) - проверяем, является ли значение вложенным объектом.3) Record - безопасная проверка на объектную структуру (в отличие от
any).4) Recursive Types (
DeepPartial) - если внутри объект, вызываем DeepPartial снова для вложенного типа.💻 Пример использования:
type User = {
name: string;
details: {
age: number;
address: {
city: string;
};
};
};
// Теперь ВСЕ поля на любом уровне вложенности стали необязательными!
type PartialUser = DeepPartial;
const user1: PartialUser = {}; // Валидно
const user2: PartialUser = {
details: {
address: {
city: "Москва", // Не обязательно передавать name или age
},
},
};