npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

type-transformer

v0.3.3

Published

Transformation / serialization / deserialization of plain JavaScript objects to typed objects and vice versa

Downloads

35

Readme

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