Exclude, Extract, NonNullable, ReturnType, InstanceType, Omit¶
Чтобы сэкономить время разработчиков, в систему типов TypeScript были включены несколько часто требующихся условных типов, каждый из которых будет подробно рассмотрен в этой главе.
Exclude (исключает из T признаки присущие U)¶
В результате разрешения условный тип Exclude<T, U>
будет представлять разницу типа T
относительно типа U
. Параметры типа T
и U
могут быть представлены как единичным типом, так и множеством union
.
1 2 3 |
|
Простыми словами, из типа T
будут исключены признаки (ключи), присущие также и типу U
.
1 2 3 |
|
В случае, если оба аргумента типа принадлежат к одному и тому же типу данных, Exclude<T, U>
будет представлен типом never
.
1 |
|
Его реальную пользу лучше всего продемонстрировать на реализации функции, которая на входе получает два разных объекта, а на выходе возвращает новый объект, состоящий из членов, присутствующих в первом объекте, но отсутствующих во втором. Аналог функции difference
из широко известной библиотеки lodash.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Extract (общие для двух типов признаки)¶
В результате разрешения условный тип Extract<T, U>
будет представлять пересечение типа T
относительно типа U
. Оба параметра типа могут быть представлены как обычным типом, так и union
.
1 2 3 |
|
Простыми словами, после разрешения Extract<T, U>
будет принадлежать к типу определяемого признаками (ключами), присущими обоим типам. То есть, тип Extract<T, U>
является противоположностью типа Exclude<T, U>
.
1 2 3 |
|
В случае, когда общие признаки отсутствуют, тип Extract<T, U>
будет представлять тип never
.
1 |
|
Условный тип Extract<T, U>
стоит рассмотреть на примере реализации функции, принимающей два объекта и возвращающей новый объект, состоящий из членов первого объекта, которые также присутствуют и во втором объекте.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
NonNullable (удаляет типы null и undefined)¶
Условный тип NonNullable<T>
служит для исключения из типа признаков типов null
и undefined
. Единственный параметр типа может принадлежать как к обычному типу, так и множеству определяемого тип union
.
1 2 3 4 5 |
|
Простыми словами, данный тип удаляет из аннотации типа такие типы, как null
и undefined
.
1 2 3 |
|
В случае, когда тип, выступающий в роли единственного аргумента типа, принадлежит только к типам null
и\или undefined
, NonNullable<T>
представляет тип never
.
1 |
|
ReturnType (получить тип значения, возвращаемого функцией)¶
Условный тип ReturnType<T>
служит для установления возвращаемого из функции типа. В качестве параметра типа должен обязательно выступать функциональный тип.
1 2 3 4 5 |
|
На практике очень часто требуется получить тип, к которому принадлежит значение, возвращаемое из функции. Единственное, на что стоит обратить внимание, что в случаях, когда тип возвращаемого из функции значения является параметром типа, у которого отсутствуют хоть какие-то признаки, то тип ReturnType<T>
будет представлен пустым объектным типом {}
.
1 2 3 4 5 6 7 8 9 10 11 |
|
InstanceType (получить через тип класса тип его экземпляра)¶
Условный тип InstanceType<T>
предназначен для получения типа экземпляра на основе типа, представляющего класс. Параметр типа T
должен обязательно принадлежать к типу класса.
1 2 3 4 5 |
|
В большинстве случаев идентификатор класса задействован в приложении в качестве типа его экземпляра.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Но сложные приложения часто требуют динамического создания своих компонентов. В таких случаях фабричные функции работают не с экземплярами классов, а непосредственно с самими классами.
Стоит напомнить, что в JavaScript классы это всего лишь синтаксический сахар над старой доброй функцией конструктором. И, как известно, объект функции конструктора представляет объект класса, содержащего ссылку на прототип, который и представляет экземпляр. Другими словами, в TypeScript идентификатор класса, указанный в аннотации типа, представляет описание прототипа. Чтобы получить тип самого класса, необходимо выполнить над идентификатором класса запрос типа.
1 2 3 4 5 6 7 8 9 |
|
Таким образом, грамотно вычислить тип экземпляра в фабричной функции можно при помощи типа InstanceType<T>
.
1 2 3 4 5 6 7 8 9 |
|
Хотя можно прибегнуть и к менее декларативному способу - к запросу типа свойства класса prototype
.
1 2 3 4 5 |
|
И последнее, о чем стоит упомянуть, что результат получения типа непосредственно через any
и never
будет представлен ими же. Остальные случаи приведут к возникновению ошибки.
1 2 3 4 5 |
|
Parameters (получить тип размеченного кортежа, описывающий параметры функционального типа)¶
Расширенный тип Parameters<T>
предназначен для получения типов, указанных в аннотации параметров функции. В качестве аргумента типа ожидается функциональный тип, на основе которого будет получен размеченный кортеж, описывающий параметры этого функционального типа.
1 2 3 |
|
Parameters<T>
возвращает типы параметров в виде кортежа.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
ConstructorParameters (получить через тип класса размеченный кортеж, описывающий параметры его конструктора)¶
Расширенный тип ConstructorParameters<T>
предназначен для получения типов, указанных в аннотации параметров конструктора.
1 2 3 |
|
В качестве единственного параметра типа ConstructorParameters<T>
ожидает тип самого класса, на основе конструктора которого будет получен размеченный кортеж, описывающий параметры этого конструктора.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Omit (исключить из T признаки, ассоциированные с ключами, перечисленными множеством K)¶
Расширенный тип Omit<T, K>
предназначен для определения нового типа путем исключения заданных признаков из существующего типа.
1 2 3 4 5 |
|
В качестве первого аргумента типа тип Omit<T, K>
ожидает тип данных, из которого будут исключены признаки, связанные с ключами, переданными в качестве второго аргумента типа.
Простыми словами, к помощи Omit<T, K>
следует прибегать в случаях необходимости определения типа, представляющего некоторую часть уже существующего типа.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|