#enableImplicitConversion weird behaviour

1 messages · Page 1 of 1 (latest)

shy arrow
#

When I set enableImplicitConversion:true it parses strings on query params to true before it even reachs class transformer
code snippet:

@Transform(({ value }) => {
    console.log('Transforming isInvited with value:', value);
if (value === undefined || value === null || value === '') return undefined;

    if (value === true) return true;
    if (value === false) return false;
   
    throw new BadRequestException(
      'isInvited must be a boolean value (true or false)',
    );  })
  @IsOptional()
  @IsBoolean({ message: field must be a boolean value (true or false)' })
  field?: boolean;

in this if I put false as query param the console log logs true

fast cape
# shy arrow When I set ```enableImplicitConversion:true ``` it parses strings on query par...

It's JavaScript. Most JavaScript-based truthiness checks (including the logic within ValidationPipe for implicit conversion) treat the non-empty string 'false' as a truthy value. Only the empty string ('') or the string '0' might be considered falsy in some contexts, but a direct boolean conversion of a non-empty string usually results in true. Therefore, the string 'false' becomes the boolean 'true'.

Set enableImplicitConversion: false, and your code like this, and it should work:

import { Transform, Expose } from 'class-transformer';
import { IsOptional, IsBoolean, BadRequestException } from 'class-validator';

export class YourDto {

  @Transform(({ value }) => {
    console.log('Transforming isInvited with value:', value, typeof value);

    if (value === undefined || value === null || value === '') return undefined;

    // Explicitly check for the string 'true' and 'false' (case-insensitive)
    const lowerValue = String(value).toLowerCase();

    if (lowerValue === 'true') return true;
    if (lowerValue === 'false') return false;

    throw new BadRequestException(
      'isInvited must be a boolean value (true or false)',
    );
  })
  @IsOptional()
  @IsBoolean({ message: 'field must be a boolean value (true or false)' })
  field?: boolean;
}
shell patrol
#

As Scott says, this is a common footgun and many developer hours have been wasted on this exact issue 😢

shy arrow
#

thanks @fast cape for the answer, I thought implicitConversion uses ts reflection tho which I thought would be more accurate than plain js truthiness , how much would the performance imact of disabling this be ?