Search code examples
javascriptreactjstypescriptreact-nativecasting

cast data received from backend to a frontend interface in typescript


I have data received from backend as following:

  id: number;
  user_id: number;
  car_brand: string;
  car_model: string;
  vin: string;
  equipment: string;
  reg_number: string;
  car_mileage: number;
  car_year: string;

and i have an interface in frontend as following: UserCarType

  id: number;
  user_id: number;
  brand: string;
  model: string;
  vin: string;
  restyling:string
  govtNumber: string;
  mileage: number;
  year: string;

as you can observe the two types are identique but only preoprty names differ, how can i cast type received from backend to the frontent interface ?

I tried to use "as" keyword but without success, still preoperties with backend names. I have found some sources where they talking about mapping and to create a fucntion that maps every function, please someone an provide me with best and effective solution ?

I also tried this:

  const car = {
    id: props.userCar.id,
    user_id: props.userCar.user_id,
    user_guid: props.userCar.user_guid,
    car_guid: props.userCar.car_guid,
    color_guid: props.userCar.color_guid,
    brand_guid: props.userCar.brand_guid,
    model_guid: props.userCar.model_guid,
    brand: props.userCar.car_brand,
    model: props.userCar.car_model,
    vin: props.userCar.vin,
    equipment: props.userCar.equip,
    govtNumber: props.userCar.reg_num,
    mileage: props.userCar.mileage,
    year: props.userCar.manuf_date,
    predictedPrice: props.userCar.sale_price,
    brandImage: props.userCar.logo,
    carImage: '', // Set the carImage property based on your data}
  };

but i would to know if there is a way to do it properly in typescript


Solution

  • Some other languages offer runtime value "casting", but TypeScript can't do that because it only exists at compile time (not runtime). The only "casting" in TypeScript is simply making compile-time type assertions (compiler overrides), and this has no effect on runtime program data (just types).

    If you're going to be copying values from an input object to a new object, but you want to copy the values to potentially different keys than the original: you might want a function to help with that task so that all you need to do is specify the mapping of input property names to output property names. Below is an example of such a function that you can modify to suit your needs:

    TS Playground

    type MappedKeys<
      PropertyMap extends Readonly<Record<string, string>>,
      Input extends Readonly<Record<keyof PropertyMap, any>>,
    > = { -readonly [K in keyof PropertyMap as PropertyMap[K]]: Input[K] };
    
    function mapKeys<
      const PropertyMap extends Readonly<Record<string, string>>,
      Input extends Readonly<Record<keyof PropertyMap, any>>,
    >(propertyMap: PropertyMap, input: Input): MappedKeys<PropertyMap, Input> {
      const result = {} as MappedKeys<PropertyMap, Input>;
      // @ts-expect-error
      for (const key in propertyMap) result[propertyMap[key]] = input[key];
      return result;
    }
    
    type ServerCar = {
      id: number;
      user_id: number;
      car_brand: string;
      // …etc.
    };
    
    const serverCar: ServerCar = {
      id: 101,
      user_id: 5432,
      car_brand: "AutoCorp",
      // …etc.
    };
    
    type ClientCar = {
      id: number;
      user_id: number;
      brand: string;
      // …etc.
    };
    
    const clientCar: ClientCar = mapKeys({
      id: "id",
      user_id: "user_id",
      car_brand: "brand",
      // …etc.
    }, serverCar);
    
    console.log(clientCar); //=> { id: 101, user_id: 5432, brand: "AutoCorp" }