I'm building an accounting application using NestJS. I have a DTO called CreateTransactionDto, and I want certain fields to be required or forbidden based on the value of transactionType. For example:
If transactionType = SALE, then fields like quantity and unitPrice must be provided, but receivedAmount must not be included.
If transactionType = PAYMENT, then receivedAmount is required, and quantity and similar fields must not be included.
Here’s how I’ve defined validation for the receivedAmount field:
// dto
@ApiProperty({
description: 'Type of the transaction',
enum: TransactionType,
})
@IsNotEmpty()
@IsEnum(TransactionType)
transactionType: TransactionType;
@ValidateIf((o: CreateTransactionDto) => o.transactionType === TransactionType.PAYMENT)
@IsNotEmpty({
message: 'Received amount is required for PAYMENT transactions',
})
@IsNumber()
@ValidateIf((o: CreateTransactionDto) => o.transactionType === TransactionType.SALE)
@IsEmpty({
message: 'Received amount should not be provided for SALE transactions',
})
receivedAmount?: number;
I'm also using the global ValidationPipe with the following configuration:
// main.ts
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
stopAtFirstError: false,
}),
);
However, when I send the following JSON payload, no validation error occurs:
{
"customerId": 1,
"transactionType": "SALE",
"transactionDate": "2023-10-01",
"description": "Sale of goods",
"quantity": 10,
"quantityUnit": "pcs",
"unitPrice": 50,
"receivedAmount": 500
}
Even though transactionType is SALE, and receivedAmount should not be included, the request goes through without validation errors.
My question is: How can I correctly use ValidateIf to conditionally validate or reject fields based on other field values? Is there something I'm missing or doing wrong?