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

Декораторы типов-помощников

Типы-помощники сообщают привязчику, как интерпретировать значение поля до запуска валидации. Они определяют, в какой класс превращается вложенный объект, к какому типу приводится каждый элемент массива и какому члену перечисления соответствует исходная строка.

@Type, @List и @Enum образуют одну категорию. К полю можно применить не более одного из них.

@Type(typeFn: TypeThunk | TypeResolver, options?: TypeOptions)​

Преобразует простой JSON-объект в экземпляр целевого класса.

  • typeFn: Функция, возвращающая целевой класс. Используйте танк () => Class для фиксированного типа или резолвер (data) => Class, чтобы выбрать класс по исходным данным.
  • options.discriminator (необязательно): Структурное сопоставление вида { property, subTypes: [{ name, value }] }. Класс выбирается по значению property.

@Type нельзя применить к полю String, Number или Boolean.

class User {
@Body()
@Type(() => Profile)
profile!: Profile
}

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

@List(elementType: ArrayElementType)​

Объявляет тип элементов поля-массива, чтобы каждый элемент приводился по отдельности.

  • elementType: String, Number, Boolean, Date, конструктор класса или один из строковых литералов 'string', 'number', 'boolean', 'date'.

@List можно применять только к полям-массивам.

class ListSample {
@Body()
@List(Number)
scores!: number[]
}

Полный пример см. в Декоратор List.

@Enum(enumObj: object, message?: string)​

Сопоставляет входящее значение с членом enumObj и отклоняет значение, которое не является членом.

  • enumObj: Объект перечисления, с которым сопоставляется значение.
  • message (необязательно): Сообщение об ошибке, которое отобразится, если значение не является членом. Если опущено, будет использовано сообщение по умолчанию.

На вход принимаются как ключ перечисления ('ADMIN'), так и его значение ('admin', 0), а в привязанном поле всегда оказывается значение перечисления. Числовая строка сравнивается численно, поэтому '0' соответствует члену со значением 0.

enum UserRole {
ADMIN = 'admin',
USER = 'user',
}

class UpdateRoleRequest {
@Body('role')
@Enum(UserRole)
role!: UserRole
}

@Enum и приводит значение, и проверяет его, но это тип-помощник, а не декоратор валидации. Отсюда следуют два следствия:

  • @Each оборачивает только декораторы валидации, поэтому @Each(Enum(UserRole)) отклоняется.
  • @Enum устанавливает собственный преобразователь, поэтому его нельзя сочетать с @Transform.

Правила схемы​

bindingCargo() проверяет правила ниже при регистрации маршрута, а не при первом запросе. Нарушение выбрасывает CargoSchemaError при запуске.

ПравилоСообщение о нарушении
Только один тип-помощник на поле@List + @Type cannot be combined; apply a single one of @Type/@List/@Enum
@List требует поля-массива@List can only be applied to array fields
@Type отклоняет примитивное поле@Type cannot be applied to a primitive field
@Each не может обернуть тип-помощник@Each cannot wrap type-helper decorator(s): @Enum
Преобразователь принадлежит @Enum@Enum cannot be combined with @Transform; @Enum installs its own transformer

В сообщении перечисляются фактически применённые декораторы в порядке вычисления (снизу вверх), поэтому начало сообщения зависит от вашего кода.