@ts-lab/auto-mapper
TypeScript icon, indicating that this package has built-in type declarations

1.0.0 • Public • Published

Auto mapper for Typescript

A very lightweight library to map objects in typescript from interfaces.

Installation

npm install @ts-lab/auto-mapper

Usage

Given these 2 interfaces:

export interface UserDto {
  id: string;
  name: string;
  surname: string;
  email: string;
  city: string;
  password: string;
}

export interface User {
  id: string;
  fullName: string;
  email: string;
  city: string;
}

Mapping interfaces

We want to map from UserDto to User, so firstly a profile is created in which we define the mapping:

  • The property full name, which is not provided in the source object, will be manually mapped
import { Profile } from "@ts-lab/auto-mapper";

const destinationInitialState: User = {
  id: '',
  email: '',
  city: '',
  fullName: '',
}

export const userProfile = new Profile<UserDto, User>(destinationInitialState)
.forMember('fullName', (source) => source.name + ' ' + source.surname)
  • An expected initial state is provided to the profile, which is used to create the destination object

  • In case the property given does not exist in the destination object, an error will be thrown

import { Profile } from "@ts-lab/auto-mapper";

const destinationInitialState: User = {
  id: '',
  email: '',
  city: '',
  fullName: '',
}

export const dtoToUserProfile = new Profile<UserDto, User>(destinationInitialState)
.forMember('fakeName', (source) => source.name + ' ' + source.surname)

// ERROR: Property 'fakeName' does not exist on type 'User'

After creating the profile we can map the objects:

  • There is no need to tell the auto mapper which interfaces will be used, it will automatically infer them from the profile
import { AutoMapper } from "@ts-lab/auto-mapper";
import { UserDto } from "./interfaces/userDto";
import { dtoToUserProfile } from "./interfaces/userProfile";

userDtoMock: UserDto = {
  id: '1',
  name: 'John',
  city: 'New York',
  email: 'email@email.com',
  password: '********',
  surname: 'Doe',
  config: '{"theme": "dark"}'
}

public ngOnInit() {
  const user = AutoMapper.map(this.userDtoMock, dtoToUserProfile);
  expectedResult = {
    id: '1',
    fullName: 'John Doe',
    city: 'New York',
    email: 'email',
    config: {
      theme: 'dark'
    }
  }
}

Mapping arrays

It would work with the same profile.

import { AutoMapper } from "@ts-lab/auto-mapper";
import { UserDto } from "./interfaces/userDto";
import { dtoToUserProfile } from "./interfaces/userProfile";

userDtoMock: UserDto = [
  {
    id: '1',
    name: 'John',
    city: 'New York',
    email: 'email',
    password: '********',
    surname: 'Doe',
    config: '{"theme": "dark"}'
  },
  {
    id: '2',
    name: 'Jane',
    city: 'New York',
    email: 'email',
    password: '********',
    surname: 'Doe',
    config: '{"theme": "dark"}'
  }
]

public ngOnInit() {
  const user = AutoMapper.mapArray(this.userDtoMock, dtoToUserProfile);
  expectedResult = [
    {
      id: '1',
      fullName: 'John Doe',
      city: 'New York',
      email: 'email',
      config: {
        theme: 'dark'
      }
    },
    {
      id: '2',
      fullName: 'Jane Doe',
      city: 'New York',
      email: 'email',
      config: {
        theme: 'dark'
      }
    }
  ]
}

Mapping classes

It can also be implemented with mixed (classes and interfaces) objects.

import { AutoMapper } from "@ts-lab/auto-mapper";
import { ToyClass } from "./classes/toy";
import { DtoToy } from "./interfaces/userProfile";

export class ToyClass {
  name: string;
  price: number;
  VPOPrice: number;
  isAvailable: boolean;

  constructor(_name: string, _price: number, _VPOPrice: number, _isAvailable: boolean) {
    this.name = _name;
    this.price = _price;
    this.VPOPrice = _VPOPrice;
    this.isAvailable = _isAvailable;
  }
}

export interface ToyDto {
  name: string;
  price: number;
  available: boolean;
}

export const dtoToyToToyProfile = new Profile<ToyDto, ToyClass>(toyInitialState)
.forMember('VPOPrice', (source) => source.price * 1.2)
.forMember('isAvailable', (source) => source.available);

 const mappedToy = AutoMapper.map<ToyDto, ToyClass>(toyDtoMock, dtoToyToToyProfile);
 console.log(mappedToy)

expectedResult = {
  name: 'Toy',
  price: 10,
  VPOPrice: 12,
  isAvailable: true
}

Package Sidebar

Install

npm i @ts-lab/auto-mapper

Weekly Downloads

6

Version

1.0.0

License

MIT

Unpacked Size

24.7 kB

Total Files

18

Last publish

Collaborators

  • alexfh