Enums and Unions
Define enumerations and discriminated unions
Enums and Unions
Enums
Enums define a fixed set of allowed values:
Zodra.enum :order_status, values: %i[draft confirmed shipped delivered cancelled]Using enums in types
Once defined, an enum becomes a field type:
Zodra.type :order do
uuid :id
order_status :status # required
order_status? :old_status # optional
endGenerated output
export const OrderStatusSchema = z.enum([
"draft", "confirmed", "shipped", "delivered", "cancelled"
]);
export type OrderStatus = z.infer<typeof OrderStatusSchema>;Unions
Discriminated unions represent a value that can be one of several shapes, distinguished by a discriminator field:
Zodra.union :payment_method, discriminator: :type do
variant :card do
string :last_four, min: 4, max: 4
string :brand
string :expiry_month, min: 2, max: 2
string :expiry_year, min: 4, max: 4
end
variant :bank_transfer do
string :bank_name
string :account_last_four, min: 4, max: 4
end
endUsing unions in types
Zodra.type :order do
uuid :id
reference :payment_method
endGenerated output
export const PaymentMethodSchema = z.discriminatedUnion("type", [
z.object({
type: z.literal("card"),
lastFour: z.string().min(4).max(4),
brand: z.string(),
expiryMonth: z.string().min(2).max(2),
expiryYear: z.string().min(4).max(4),
}),
z.object({
type: z.literal("bank_transfer"),
bankName: z.string(),
accountLastFour: z.string().min(4).max(4),
}),
]);
export type PaymentMethod = z.infer<typeof PaymentMethodSchema>;Discriminator
The discriminator option specifies which field distinguishes variants. Each variant name becomes the literal value of that field.
# discriminator: :type means each variant gets a `type` field
# variant :card → type: "card"
# variant :bank_transfer → type: "bank_transfer"