typestack/class-transformer

question: Casting Json to the required datatype

AhmedK-Fawry opened this issue · 3 comments

I attempted to convert a JSON object to a Restaurant class using the class-transformer library in TypeScript. Below is the code snippet:

import { plainToClass, classToPlain } from 'class-transformer';

export class Restaurant {
  accountNumber?: string;
  monthlyVolume?: number;
  printingTicketEnabled?: string;
  royalPartner?: boolean;
}

export class Convert {
  public static toRestaurant(json: string): Restaurant[] {
    const objectArray: object[] = JSON.parse(json);
    const result: Restaurant[] = objectArray.map((entity) =>
      plainToClass(Restaurant, entity)
    );
    return result;
  }

  public static restaurantToJson(value: Restaurant[]): string {
    const plainObjects = value.map((entity) => classToPlain(entity));
    return JSON.stringify(plainObjects);
  }
}

However, I encountered an issue with the API sending JSON data with varying data types, such as printingTicketEnabled being either a string or a boolean.

I'm seeking a solution to enforce a specific data type (string in this case) for certain properties in the class. If the API sends a different data type, I want to attempt casting it to the specified type instead of excluding it.

I came across { excludeExtraneousValues: true }, but it excludes values. I'm looking for a way to cast the value to the specified data type instead of excluding it. How can I achieve this modification in the code?

Hi Ahmed,

This answer is a bit late, but hopefully it can be helpful!

You can use @Type(() => String) decorator to force type conversion to String in your case!

Your class would look like this:

export class Restaurant {
  @Type(() => String)
  accountNumber?: string;
  @Type(() => Number)
  monthlyVolume?: number;
  @Type(() => String)
  printingTicketEnabled?: string;
  @Type(() => Boolean)
  royalPartner?: boolean;
}

If you need a custom transformer you can read more here

Note: The plainToClass and classToPlain are marked as deprecated. You should use plainToInstance and instanceToPlain respectively.
Note2: The plainToInstace and instanceToPlain functions work with array as well! So you don't need the Array.map.

Closing as answered. If you have any questions left feel free to comment on this issue.

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.