Type Helper Decorators
Type helpers tell the binder how to interpret a field's value before validation runs. They decide which class a nested object becomes, which type each array element is cast to, and which enum member a raw string maps to.
@Type, @List, and @Enum form a single category. At most one of them may be applied to a field.
@Type(typeFn: TypeThunk | TypeResolver, options?: TypeOptions)
Converts a plain JSON object into an instance of the target class.
typeFn: A function returning the target class. Use a thunk() => Classfor a fixed type, or a resolver(data) => Classto pick the class from the raw data.options.discriminator(optional): Structural mapping in the form{ property, subTypes: [{ name, value }] }. The class is selected by the value ofproperty.
@Type cannot be applied to a String, Number, or Boolean field.
class User {
@Body()
@Type(() => Profile)
profile!: Profile
}
See Type Transformation & Polymorphism for nested mapping, circular references, and dynamic resolution.
@List(elementType: ArrayElementType)
Declares the element type of an array field so that every element is cast individually.
elementType:String,Number,Boolean,Date, a class constructor, or one of the string literals'string','number','boolean','date'.
@List can only be applied to array fields.
class ListSample {
@Body()
@List(Number)
scores!: number[]
}
See List Decorator for a full example.
@Enum(enumObj: object, message?: string)
Maps the incoming value onto a member of enumObj, and rejects a value that is not a member.
enumObj: The enum object to map against.message(optional): The error message to display when the value is not a member. If omitted, a default message will be used.
Both the enum key ('ADMIN') and the enum value ('admin', 0) are accepted as input, and the bound field always holds the enum value. A numeric string is compared numerically, so '0' matches the member whose value is 0.
enum UserRole {
ADMIN = 'admin',
USER = 'user',
}
class UpdateRoleRequest {
@Body('role')
@Enum(UserRole)
role!: UserRole
}
@Enum both casts and checks the value, but it is a type helper, not a validation decorator. Two consequences follow:
@Eachwraps validation decorators only, so@Each(Enum(UserRole))is rejected.@Enuminstalls its own transformer, so it cannot be combined with@Transform.
Schema Rules
bindingCargo() checks the rules below when the route is registered, not on the first request. A violation throws CargoSchemaError at startup.
| Rule | Violation message |
|---|---|
| Only one type helper per field | @List + @Type cannot be combined; apply a single one of @Type/@List/@Enum |
@List requires an array field | @List can only be applied to array fields |
@Type rejects a primitive field | @Type cannot be applied to a primitive field |
@Each cannot wrap a type helper | @Each cannot wrap type-helper decorator(s): @Enum |
@Enum owns the transformer | @Enum cannot be combined with @Transform; @Enum installs its own transformer |
A message names the decorators you actually applied, listed in decorator evaluation order (bottom-up), so the leading part varies with your code.