DevGang
Авторизоваться

Типы утилит в Typescript.

В нашей повседневной жизни как разработчику программного обеспечения нам обычно нужно манипулировать данными и типами для нескольких целей: обновить запись в базе данных, сопоставить DTO (Data Transfer Object), структурировать наш возврат клиенту и многое другое.

В Typescript у нас есть некоторые ресурсы, которые помогают нам обрабатывать преобразования этого типа объектов, называемые Utility Types.

Что такое преобразования типов объектов?

Преобразования типа объекта относятся к созданию измененного типа из существующего типа или интерфейса, который представляет объект.

Круто, теперь мы знаем об этих ресурсах Typescript и о преобразованиях типов объектов. Итак, давайте посмотрим на примеры.

Некоторые типы утилит, описанные здесь, доступны только в Typescript 3.5 или выше.

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

Partial

  • Делает все свойства объекта необязательными.

Определение синтаксиса:

type Partial<T> = {[A in keyof T]?: T[A]};

Верно, но что означает приведенный выше пример?

Мы знаем, что тип T передается в Partial, в приведенном ниже примере это IUser.

interface IUser {
  uid: string;
  name: string;
  age: number;
};

Итак, keyof T в нашем примере будет keyof IUser, другими словами keyof IUser это эквивалент ключей нашего объекта (в нашем примере: "uid"|"name"|"age").

[A in "uid" | "name" | "age"]?

Следовательно, A должен быть любым ключом свойств типа IUser.

['uid']? = IUser['uid']
['name']? = IUser['name']
['age']? = IUser['age']

Все ключи со знаком вопроса (?) должны показывать, что ключ свойства является необязательным. Затем Partial создает еще один интерфейс IUser (называемый PartialIUser в нашем примере ниже) со всеми необязательными ключами.

interface PartialIUser {
  uid?: string;
  name?: string;
  age?: number;
};

Пример использования

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

Omit

  • Удаляет ключи из типа объекта.

Определение синтаксиса:

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

Возможно, вы заметили, что тип Omit основан на использовании двух других типов утилит: Pick и Exclude (мы поговорим о Pick позже).

Omit определение равно:

 Pick<T, Exclude<keyof T, K>>

Используя наш интерфейс IUser из предыдущего примера, опять же, T — это наш IUser, а K — строковый литерал ключей, удаленных из T, т. е. наш IUser.

Давайте посмотрим пример.

Пример использования

В следующем примере мы используем Omit, чтобы удалить ключ "age" из нашего интерфейса IUser и установить новый тип IUserWithoutAge в новую переменную. В этой переменной свойство "age" недоступно и не может быть использовано.

Обратите внимание, что можно опустить несколько ключей из объекта, передав объединение строковых литералов в K:

type IUserWithoutAgeAndName = Omit<IUser, "age" | "name">;

Pick

  • "Хранит" только указанные ключи.

Определение синтаксиса:

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

Pick создаст новый объект. Таким образом, невозможно использовать примитивный тип (например, строку или число) в качестве нового типа.

Разбивая определение синтаксиса и используя наш интерфейс IUser в качестве примера, мы имеем следующее:

  • T[P] — это способ доступа к типу свойства. Итак, если нам нужен доступ к свойству «возраст» из нашего интерфейса IUser, мы можем сделать так: IUser['age'].
  • Опять же, keyof T — это ключи нашего типа, в этом примере IUser interface и ключи «uid», «name» и «age».
  • И у нас есть [P in K], что означает, что свойство P должно быть одним из ключей, извлеченных из K. Тогда P может быть либо "uid", либо "name", либо "age".

Пример использования

В приведенном выше примере мы выбрали ключ "age", поэтому для переменной типа IUserWithOnlyAge нужно установить только ключ "age", другие свойства «uid» и «name» недоступны.

Readonly

  • Включите все свойства только для чтения.

Определение синтаксиса:

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

Понимание определения синтаксиса:

  1. Как и в предыдущих примерах, T[P] — это способ доступа к типу свойства, а keyof T — это ключи нашего типа.
  2. Префикс readonly — это ключевое слово машинописного текста, которое делает свойство доступным только для чтения в классе, типе или интерфейсе.

Так что, по сути, для каждого свойства нашего типа мы делаем это свойство доступным только для чтения.

Пример использования

Приведенный выше пример показывает нам, что попытка присвоить переменной newUser тип с IUserReadonly вызовет ошибку компиляции.

Вывод

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

Служебные типы помогают нам справляться с преобразованием и манипулированием данными и могут улучшить наш код, делая его более чистым, и их следует использовать с умом.

#TypeScript #Начинающим
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу