Перейти к основному содержимому
Модуль 4 · Урок 2 из 28/14 в курсе~15 min
Уроки модуля (2/2)

Типы утилит

TypeScript предоставляет несколько глобальных типов утилит для упрощения распространенных преобразований типов. Эти типы являются универсальными и позволяют декларативно создавать новые типы из существующих.

Четыре наиболее часто используемых типа утилит:

1. Partial<T>

Делает все свойства типа T необязательными. Это чрезвычайно полезно для функций обновления/исправления, где вызывающая сторона может предоставить только подмножество полей:

TS
interface User {
  id: number;
  name: string;
  email: string;
}

// All properties of User become optional: { id?: number; name?: string; email?: string; }
type UserUpdate = Partial<User>;

2. Readonly<T>

Делает все свойства типа T только для чтения. Любая попытка переназначить свойство вызовет ошибку компилятора во время компиляции:

TS
interface Point {
  x: number;
  y: number;
}

const p: Readonly<Point> = { x: 10, y: 20 };
// p.x = 5; // Error: cannot assign to 'x' because it is a read-only property

3. Pick<T, Keys>

Создает тип, выбирая только определенный набор ключей (представленный объединением строк) из типа T:

TS
interface Article {
  id: number;
  title: string;
  content: string;
  views: number;
}

// Selects only 'title' and 'views': { title: string; views: number; }
type ArticlePreview = Pick<Article, 'title' | 'views'>;

4. Omit<T, Keys>

Создает тип путем удаления определенного набора ключей из типа T. Это двойник Pick:

TS
interface Product {
  id: number;
  name: string;
  price: number;
  secretVendorCode: string;
}

// Removes 'secretVendorCode': { id: number; name: string; price: number; }
type PublicProduct = Omit<Product, 'secretVendorCode'>;

5. Record<Keys, Type>

Создает тип объекта, ключи свойств которого — Keys, а значения свойств — Type. Это чрезвычайно полезно для сопоставления ключей со значениями, представляющими словари или хеш-таблицы (карты ключ-значение):

TS
type Page = 'home' | 'about' | 'contact';

interface PageInfo {
  title: string;
}

// Creates a dictionary with keys 'home' | 'about' | 'contact' and values PageInfo
const nav: Record<Page, PageInfo> = {
  home: { title: 'Home Page' },
  about: { title: 'About Us' },
  contact: { title: 'Contact Us' },
};

Попробуйте сами

Упражнение 1. Обновление профиля с помощью частичного

Упражнение#ts.m4.l2.e1
Попыток: 0Загрузка…

Завершите функцию updateProfile, которая принимает исходный профиль (Профиль) и объект обновлений (обновления), где все поля Профиля являются необязательными. Он должен вернуть новый объект Profile, сочетающий исходные свойства с обновлениями.

Загрузка редактора…
Показать подсказку

Используйте тип утилиты Partial<Profile> для параметра обновлений и оператор расширения для объединения объектов: { ...original, ...updates }.

Решение доступно после 3 попыток

Упражнение 2. Удаление чувствительных полей с помощью Omit

Упражнение#ts.m4.l2.e2
Попыток: 0Загрузка…

Учитывая тип UserAccount, определите псевдоним типа с именем SafeUser, в котором отсутствует конфиденциальное свойство пароляHash.

Загрузка редактора…
Показать подсказку

Используйте тип SafeUser = Omit<UserAccount, 'passwordHash'>; опустить указанное поле.

Решение доступно после 3 попыток

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

Упражнение#ts.m4.l2.e3
Попыток: 0Загрузка…

Учитывая тип AppConfig, определите псевдоним типа с именем PublicConfig, который является версией только для чтения (Readonly), содержащей только свойства apiEndpoint и порта, выбранные с помощью Pick.

Загрузка редактора…
Показать подсказку

Используйте тип PublicConfig = Readonly<Pick<AppConfig, 'apiEndpoint' | 'порт'>>;

Решение доступно после 3 попыток

Упражнение 4. Реестр пользователей с режимом записи и только для чтения

Упражнение#ts.m4.l2.e4
Попыток: 0Загрузка…

Учитывая пользовательский интерфейс с полями id:number и name:string, создайте тип ReadOnlyUser, который сделает все поля в User только для чтения. Затем создайте тип UserRegistry, представляющий словарь, где ключом является строка (например, идентификатор строки), а значением — ReadOnlyUser.

Загрузка редактора…
Показать подсказку

Используйте Readonly<User> для определения ReadOnlyUser и Record<string, ReadOnlyUser> для реестра.

Решение доступно после 3 попыток