0.3.3 • Published 3 years ago

type-transformer v0.3.3

Weekly downloads
-
License
MIT
Repository
bitbucket
Last release
3 years ago

type-transformer

type-transformer is a TypeScript / JavaScript library for transforming plain JavaScript objects into instances of a class and vice versa. That is especially useful when you receive objects from an API and want them to be of a certain type in your application - which means they have all the methods and properties associated with that type.

This library can be used in frontend and backend. It has no dependencies.

Documentation

The basics are covered below. For in-depth documentation have a look at the wiki.

What exactly does type-transformer do?

In JavaScript there are two types of objects:

  • plain (literal) objects
  • typed (constructor) objects

Plain objects are objects that are instances of the Object class. Those might be literal objects, created via {} notation. Typed objects are instances of classes with an own constructor, properties, and methods. Usually you define them via class notation. type-transformer lets you convert between plain and typed objects and vice versa.

The problem

Sometimes you want to transform plain JavaScript objects to the ES6 classes you defined. If you are getting data from an API, maybe as JSON which you then JSON.parse, you have plain JavaScript objects, not instances of one of your classes.

For example you have a list of persons in your persons.json that you are loading:

[{
  "firstName": "Johny",
  "lastName": "Cage",
  "age": 27
},
{
  "firstName": "Ismoil",
  "lastName": "Somoni",
  "age": 50
},
{
  "firstName": "Luke",
  "lastName": "Dacascos",
  "age": 12
}]

And you have a Person class:

export class Person {
    firstName: string;
    lastName: string;
    age: number;

    getName() {
        return this.firstName + '  ' + this.lastName;
    }

    isAdult() {
        return this.age > 36 && this.age < 60;
    }
}

You want to have an array of object of type Person, however, you only get plain objects:

fetch('persons.json').then((response:Response) => {
    response.json().then((persons: Person[]) => {
        // you can use persons here, and type hinting also will be available,
        // but persons are not actually instances of the Person class, their
        // methods will not be available.
    });
});

Here you can use persons[0].firstName and persons[0].lastName. However, you cannot use persons[0].getName() or persons[0].isAdult() because "persons" actually is an array of plain javascript objects, not instances of the Person class. It seems as if they are actually typed objects, but they are not. TypeScript only assumes they are, because you told it so.

The solution

With type-transformer you can easily transform that array of plain objects into an array of typed objects:

fetch('persons.json').then((response:Response) => {
    response.json().then((persons: Person[]) => {
        const realPersons = plainToClass(persons, Person);
        // each person in realPersons is instance of Person class 
    });
});

Now you can use persons[0].getName() and persons[0].isAdult() methods.

What else can type-transformer do?

Expose data from your API

If you have an API which returns objects (instead of JSON or other serialized data) type-transformer can transform your typed objects with methods for internal logic into plain JavaScript objects. You can easily configure that process and (dynamically) decide which properties to expose or how certain values should be transformed.

Features

(in arbitrary order)

  • Handle circular references (resolve or preserve them or fail)
  • Convert from/to immutable.js Maps
  • Multiple APIs: fluent API, decorators
  • Multiple schemas per class
  • Respect inheritance
  • Method fields
  • Custom transformations
  • ...

Installation

Node.js

  1. Install the module:

    npm install type-transformer --save

  2. ES6 features are used, if you are using an old version of node.js, you may need to install es6-shim:

    npm install es6-shim --save

    and import it in a global place like app.ts:

    import "es6-shim";

Browser

  1. Install module:

    npm install type-transformer --save

  2. If you are using system.js you may want to add this into map and package config:

    {
        "map": {
            "type-transformer": "node_modules/type-transformer"
        },
        "packages": {
            "type-transformer": { "main": "index.js", "defaultExtension": "js" }
        }
    }

Alternatives

1. Object.assign

There is a builtin (not in IE though) which can assign properties of one object to another. So you can instantiate an empty typed object and then copy over the properties from the plain object:

var personInstance = Object.assign(new Person(), personLiteral);

2. Manually copy properies

You can iterate over the properties of an object and manually copy them over. This is probably the most flexible and at the same time most tedious variant.

var personInstance = new Person();
for (var prop in personLiteral)
    personInstance[prop] = personLiteral[prop];

3. Use JSON

At least for transforming your typed objects into plain objects you can simply use JSON. It has been optimized a lot and is really fast. However, there are some disadvantages to that:

  • only works for creating plain objects
  • fails when there are circular references
  • mercilessly serializes everything it can find in any object

4. Use class-transformer

That's probably the best alternative. type-transformer is inspired by and borrows some code and documentation from class-transformer. It's a great library with essentially the same objectives. There are some advantages and disadvantages.

Advantages of class-transformer:

  • it is older and thus might have fewer bugs and more snippets you can find online
  • it has some features type-transformer doesn't have yet, such as versioning and groups; you're welcome to file an issue for things you're missing, though

Advantages of type-transformer:

  • you can define more than one schema per class (that's one of the main reasons why this library has been created instead of using class-transformer)
  • it has an api that let's you programmatically define schemas
  • you can easily define schemas for classes defined outside your project
0.3.2

3 years ago

0.3.3

3 years ago

0.3.1

3 years ago

0.3.0

3 years ago

0.2.3

5 years ago

0.2.2

5 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago