Sunday, January 20, 2019

Setting up basic typescript project

Typescript is getting popularity day by day, it is basically a different version of Javascript and has more features as well as more properties of a Typed Language as opposed to the default behavior of the Javascript.

Here is a basic example of a function in typescript:

1
const add = (a: number, b: number) => a + b;

As you can see, the part of the code where we have declared a: number and b: number is not a pure Javascript rather, its a feature provided by Typescript and is very useful in a real sense.

Today we are going to configure a normal typescript project and for that, you need the following prerequisites:
  1. npx module installed globally 
  2. typescript module installed globally
  3. tslint module installed globally
For all the above 3 just type: npm install -g npx typescript tslint and it will install all the 3 modules. 
typescript comes with 2 executables namely: tsc and tsserver

tsc  is the typescript compiler that compiles the .ts files and converts them to pure JS files.
tsserver is basically the typescript server.
  1. First, we will create a config file for the typescript project, for that we will use the command:
    tsc --init (- in the folder where we want to start our typescript project.)
  2. This will generate a tsconfig.json file with the following content:

    1
    2
    3
    4
    5
    6
    7
    {
      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "strict": true
      }
    }

  3. We are going to add some more options in this configuration, So after that, the tsconfig.json will look like:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    {
      "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "strict": true,
        "outDir": "dist",
        "sourceMap": true,
      },
      "include": [
        "src/**/*"
      ],
      "exclude": [
        "node_modules",
        "**/*.spec.ts"
      ]
    }
    

  4. Now we will create a script to compile the .ts files and convert them to .js files. For that, we will take npm's help.
  5. For that, we will initiate the npm and add the script for the conversion.
  6. npm init -y will generate the default package.json with the basic setup. Just add these 2 sections in package.json:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    .......
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "compile": "rimraf dist/ & tsc"
      },
      "devDependencies": {
        "rimraf": "^2.6.3",
        "typescript": "^3.2.2"
      },
      .......
      .......
    

  7. Now let us create a typescript file with .ts extension and then we will compile the .ts into .js.
  8. Here is a basic .ts file: src/index.ts

    1
    2
    3
    4
    5
    function helloWorld(word: string = "Ankur"): string {
        return `Hello ${word}`;
    }
    
    console.log(helloWorld("World"));
    

  9. Here is the folder structure:

  10. If you have node_modules folder skip this otherwise run:  npm install 
  11. After all is set up, run the command npm run compile (we are using the part of point 6, at line number 4)
  12. After this command, a folder named dist will get generated and it will look like this:


  13. Now you can run the file using node dist/index.js command.
The main purpose of this project is that we are going to write the code in typescript and then we are going to compile the same in pure javascript so that it can be run using the node js framework since node js does not understand the typescript.

The above code is available here.

We have a shortcut way as well to do all the tiring work by itself, using a generator of the Typescript project namely gts, which can be found https://github.com/google/ts-style.

For the shortcut here are the commands:
  1. npx gts init
  2. It will ask you whether or not to generate the package.json, press (y) and enter.
  3. It will generate the project with the following structure (with node_modules/), (I deleted it intentionally, since showing the structure is not possible with that folder.):

  4. This project will have all the basic settings up and ready with typescript settings that are being used by Google Node Js team.
  5. Write your personal code inside src/ and the scripts are mentioned in package.json that are available like:
    1. npm run fix - Will fix the inconsistent & messy code 
    2. npm run check - Will check the code with the guidelines mentioned in tsconfig.json and outputs the problem
    3. npm run clean - Will cleans the code with respect to linting errors, and all possible fixes.
    4. npm run compile - Will take your .ts code and builds it to .js files under build/
Note:
  • In case you use console.log in your code (in the project created by gts), you might get the error like this:

  • In this case, go to node_modules/gts/tsconfig-google.json and add "dom" in lib key (which is an array of strings in nature), finally, the option will look like this:  "lib": ["es2016", "dom"],
  • Come back to the main file and compile the project, you will not see the error.

That's it for typescript basic demo, meet you all soon, thanks and

Happy Coding :)

Monday, January 14, 2019

Iterators in Javascript

Javascript is becoming mature day by day, and in order to make it much interactive and better in the ways of coding, ECMAScript keeps on adding different features to it.

One of the new features (not so new, 😜), is the Iterators & Iterables.

So in a layman language, Iterators & Iterables go hand in hand.

Iterables are those objects(Classes in the real sense) those have implemented the Iterator function.

Now comes the question what is iterable, so, anything that can be iterated is termed as Iterable and the property that makes it iterable is the Iterator.

1. Explanation

So, here is the quick info regarding the things we read till now:
  1. Iterable: is basically a property that needs to be implemented to make a class/object iterable. This is done by implementing a method whose key is Symbol.iterator. Symbol.iterator is a factory of iterators.
  2. Iterator: is a function that returns a function named next() which again returns an object with 2 keys namely: done & value, so a basic iterator() looks like this:

    1
    2
    3
    4
    5
    6
    7
    8
    return{
        next(){
            return({
                done: true/false, //boolean
                value: item, //item to be read
            })
        }
    }
    
2. Questions

2.1 Q:
Now the question arises, where are these iterators useful, so let's take a look at the traversing an array in a normal fashion.

1
2
3
let a = [1, 2, 3, 4];
for(let i=0; i < a.length; i++)
   console.log(a[i]);

A: Same functionality with for..of loop, that internally uses the iterators, to traverse the array or any iterable.

1
2
for(let v of a)
	console.log(v)

As you can see how clean and compact it is, to traverse an iterable if the iterators are implemented in a proper manner.

2.2 Q: Now how do you tell whether a class implemented the iterator or not?

A: If console.log(typeof array[Symbol.iterator]) returns a function that means the Iterator is implemented and the object of that class can be browsed or traversed using the special for loops.

Now let us take a basic example, where I created the Class with 2 variables and then I implemented the iterator in order to traverse all the variables of the object of the same class.

For the reference here is the code.

Let us try to see the code in detail. So basically code has 2 files, User.js (the class) and index.js (file that created the object of User class and tries to utilize iterator.)

User.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class User {
    constructor({name, age}){
        this.name = name;
        this.age = age;
    }

    getAge(){ return this.age; }
    getName(){ return this.name; }

    setName(name){ this.name = name; }
    setAge(age){ this.age = age; } 

    //this is the property that needs to be implemented for iterators
    [Symbol.iterator]() {
        let self = this;
        let data = Object.keys(this);
        return{
            next(){
                return({
                    done: data.length === 0,
                    value: self[data.pop()]                
                })
            }
        }
    }
}

module.exports = User;

index.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
let User = require("./User");

let user1 = new User({name: 'AV', age: 31});
let user2 = new User({name: 'AV', age: 32});

console.log('\nIterating USER1')
for(const a of user1) {
    console.log(a)
}
console.log('\nIterating USER2')
for(const a of user2) {
    console.log(a)
}

The code of User.js is pretty simple, we have created a class that takes 2 parameters namely, name & age, but the catch is at line no 14, User.js.

At line 14, User.js, we have implemented the iterator for the class User, and in order to do that we have called a function named [Symbol.iterator] & have provided the functionality of the iterator. In that iterator, we have returned a function at line 17, with the structure we discussed at point 1.2 (under Explanation section)

The iterator is a function that returns a function named next() & it internally returns an object with 2 keys, namely done (line no 20, User.js) & value (line no 21, User.js).

In the iterator, we are taking the value from the self-object (line no 15, User.js) and the done value is the boolean that checks whether all values of the object are traversed or not.

The code of index.js is pretty straight forward, as we are just traversing the object (keys) using for..of loop at line 7 & 11, index.js.

Note: The example I took is a basic example of showing the functionality of Iterators, although implementing the iterator in this fashion is not a good practice.

Hope you enjoyed and understood the Iterators.


Happy coding.
:)