Home > Software design >  How to transform api data to DTO (Data Transfer Object) in TypeScript
How to transform api data to DTO (Data Transfer Object) in TypeScript

Time:03-19

I have an array of vehicles like below.

export const fetchDataFromApi = () => {
  return [
    { vehicleId: 1, vehicleType: 'car', seats: 4, wheelType: 'summer', updatedAt: new Date().toISOString },
    { vehicleId: 2, vehicleType: 'plane', seats: 200, maxAltitude: 8000, updatedAt: new Date().toISOString },
    { vehicleId: 3, vehicleType: 'train', seats: 1200, railType: 'whatever', updatedAt: new Date().toISOString },
  ];
};

I have created Vehicle, Car, Plane and Train classes. But I am not sure, those could be Interface too.

This API response should be handled with a DTO which defines the type of the response and enables casting the response into the DTO type.

So how can I transform the data into a typed DTO? Below is my class definitions but I am not sure how to implement it..

class Vehicle {
      vehicleId: number;
      vehicleType: string;
      seats: number;
      updatedAt: string;

      constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string) {
        this.vehicleId = vehicleId;
        this.vehicleType = vehicleType;
        this.seats = seats;
        this.updatedAt = updatedAt;
      }
    }

    class Car extends Vehicle {
      wheelType: string;

      constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string, wheelType: string) {
        super(vehicleId, vehicleType, seats, updatedAt);
        this.wheelType = wheelType;
      }
    }

    class Plane extends Vehicle {
      maxAltitude: number;
      constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string, maxAltitude: number) {
        super(vehicleId, vehicleType, seats, updatedAt);
        this.maxAltitude = maxAltitude;
      }
    }

    class Train extends Vehicle {
      railType: string;
      constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string, railType: string) {
        super(vehicleId, vehicleType, seats, updatedAt);
        this.railType = railType;
      }
    }

CodePudding user response:

You just need create a mapper to transform the dataset.

const fetchDataFromApi = (): Vehicle[] => {
    return [
      { vehicleId: 1, vehicleType: 'car', seats: 4, wheelType: 'summer', updatedAt: new Date().toISOString },
      { vehicleId: 2, vehicleType: 'plane', seats: 200, maxAltitude: 8000, updatedAt: new Date().toISOString },
      { vehicleId: 3, vehicleType: 'train', seats: 1200, railType: 'whatever', updatedAt: new Date().toISOString },
    ];
  };
  
  class Vehicle {
        vehicleId: number;
        vehicleType: string;
        seats: number;
        updatedAt: string;
  
        constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string) {
          this.vehicleId = vehicleId;
          this.vehicleType = vehicleType;
          this.seats = seats;
          this.updatedAt = updatedAt;
        }
      }
  
      class Car extends Vehicle {
        wheelType: string;
  
        constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string, wheelType: string) {
          super(vehicleId, vehicleType, seats, updatedAt);
          this.wheelType = wheelType;
        }
      }
  
      class Plane extends Vehicle {
        maxAltitude: number;
        constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string, maxAltitude: number) {
          super(vehicleId, vehicleType, seats, updatedAt);
          this.maxAltitude = maxAltitude;
        }
      }
  
      class Train extends Vehicle {
        railType: string;
        constructor(vehicleId: number, vehicleType: string, seats: number, updatedAt: string, railType: string) {
          super(vehicleId, vehicleType, seats, updatedAt);
          this.railType = railType;
        }
      }
  
  
  const vehicleMapper = (vehicle: Vehicle) => {
    const {vehicleId, vehicleType, seats, updatedAt} = vehicle;
    switch(vehicle.vehicleType) {
      case 'car':
        const {wheelType} = vehicle as Car;
        return new Car(vehicleId, vehicleType, seats, updatedAt, wheelType);
      case 'plane':
        const {maxAltitude} = vehicle as Plane;
        return new Plane(vehicleId, vehicleType, seats, updatedAt, maxAltitude);
      case 'train':
        const {railType} = vehicle as Train;
        return new Train(vehicleId, vehicleType, seats, updatedAt, railType);
      default:
        return new Vehicle(vehicleId, vehicleType, seats, updatedAt);
    }
  }



const data = fetchDataFromApi();
const vehicles = data.map(vehicleMapper);

CodePudding user response:

I think this would suffice...

export const fetchDataFromApi: Vehicle[] = () => ...
  • Related