Sunday, October 28, 2018

JavaScript - OOPS - Objects - JavaScript Object Literals

JavaScript is all about objects. In order to learn about object-oriented programming, we need to have a good understanding about objects.

JavaScript Object Literals:

In ECMA 6, to create a variable we use the keyword let. Before ECMA 6 was released, to create a variable we used to  use var keyword. But, from ECMA 6 onwards, we use the keywords let or const. With const we cannot reassign the variable - because, it indicates a constant.

So, here I am creating a rectangle variable and assigning it to an object.
const rectangle = {};

Here, the curly braces indicate an object literal syntax. In JavaScript, object is a collection of key value pairs.

const rectangle = {
length:1,
width:5,
location: {
x:1,
y:1
},
draw: function(){
console.log("draw");
}
};

rectangle.draw();


In this object, the variables:

  • length
  • width

... are called properties.

The variable:

  • location. 

is another object. The location object consists of couple of key - value pairs :

  • x
  • y

Also we have the variable:

  • draw

.. a function is assigned to this variable.

This rectangle object has 4 members:

  • length
  • width
  • location
  • draw

If a member is a function, we call it - method. The other members are called properties.


##
Member Name
Member Type
1
length
property
2
width
property
3
location
property
4
draw
method



We can call the members of an object using the dot notation (.). Since, we want to call the draw method from the rectangle object, we call it as:

rectangle.draw();

TypeScript - DataTypes - Function Type

 TypeScript has a function type. Not a function, but an actual datatype representing a function. Now, consider our previous example of a add function.

// function add to check for datatypes of arguments
function add(input1:number,input2:number):number{
var myResult = input1 + input2;
return myResult;
}


also, consider the greet function:
//void type
function greet():void{
console.log("Greetings! Welcome to getCity.ts");
}


Now, if we want to assign both add() and greet function to a single variable. We can do it like this:
let myAdd;
myAdd = add;
console.log("calling myAdd() == "+myAdd(2,3));
myAdd = greet;
console.log("calling myAdd() == ");
myAdd();

Now, if we try to compile this:
$ tsc getCity.ts
$

The compiler did not complain. But, we know that greet() function and add() function are clearly different. This is because they both take different number of input parameters and return a different number of return types.

To be able to set a function type, we need a function type. This is so that, we can combine all add() related functions having the same input parameters and return types. To be able to fix the add() function to a datatype, let us see the following:
// function types
let myAdd: (input1:number, input2:number) => number;

In this case, we are saying, the function myAdd()has two input parameters and both are numbers. Also, we have set its return type to be a number. So, now if we assign both add() and greet() function to myAdd() function and try to compile:

// function types
let myAdd: (input1:number, input2:number) => number;
myAdd = add;
console.log("calling myAdd() == "+myAdd(2,3));
myAdd = greet;
console.log("calling myAdd() == ");
myAdd();

On compiling this time:

$ tsc getCity.ts
getCity.ts:29:1 - error TS2322: Type '() => void' is not assignable to type '(input1: number, input2: number) => number'.
  Type 'void' is not assignable to type 'number'.

29 myAdd = greet;
   ~~~~~

getCity.ts:31:1 - error TS2554: Expected 2 arguments, but got 0.

31 myAdd();
   ~~~~~~~

  getCity.ts:26:13
    26 let myAdd: (input1:number, input2:number) => number;
                   ~~~~~~~~~~~~~
    An argument for 'input1' was not provided.

$

.. the compiler complains.  This is because myAdd() is now a function type. To be able to make the compiler to compile. We can remove associating greet() function with myAdd().

// function types
let myAdd: (input1:number, input2:number) => number;
myAdd = add;
console.log("calling myAdd() == "+myAdd(2,3));


$ tsc getCity.ts
$

Now, the compiler has compiled the code as myAdd() function type is associated with the correct function.



TypeScript - DataTypes - Types in Function Arguments

Functions can take advantage of types. Consider the function:

let myCity:string = "Hyderabad";

function getCity(){
return myCity;
}

console.log("getCity() == "+getCity());


Console Output:
getCity.js:5 getCity() == Hyderabad

Now, we modify the function such that we make the datatype of the return type explicit:

let myCity:string = "Hyderabad";

function getCity():string{
return myCity;
}

console.log("getCity() == "+getCity());

Now, I do get the same output at the console.

Console Output:
getCity.js:5 getCity() == Hyderabad

But, now if change the return value to return a number.

let myCity:string = "Hyderabad";

function getCity():string{
return 34;
}

console.log("getCity() == "+getCity());

I receive a compilation error:
getCity.ts:4:5 - error TS2322: Type '34' is not assignable to type 'string'.

This i because TypeScript will not allow the program to compile with a wrong return type.

void - using it as a return type:

//void type
function greet():void{
console.log("Greetings! Welcome to getCity.ts");
}

greet();

Console Output:
getCity.js:3 Greetings! Welcome to getCity.ts

But, it will give me an error when I try to return using this function:
getCity.ts:4:5 - error TS2322: Type '1234' is not assignable to type 'void'.

It is good to know what a function returns. But, many times the functions will have arguments and we will want a way to tell the types of the arguments being accepted by the function.

functions with types:
functions can be associated with type information with its:

  • arguments
  • return type


Consider the following example in TypeScript:
// function add to check for datatypes of arguments
function add(input1:number,input2:number):number{
var myResult = input1 + input2;
return myResult;
}

console.log("add(4,5) == "+add(4,5));

Console Output:
getCity.js:6 add(4,5) == 9

Now, if i change the last line of the above code snippet to:
console.log("add(4,5) == "+add(4,"5"));

Typescript issues the following compilation error:
$ tsc getCity.ts
getCity.ts:7:34 - error TS2345: Argument of type '"5"' is not assignable to parameter of type 'number'.

We can see that TypeScript protects me from accidentally passing a string input to to a add function.


Reference:



Saturday, October 27, 2018

TypeScript - DataTypes - Enums

enums are a feature provided by TypeScript that make numbers more expressive.

Consider a case you have a number of food items and each food item is represented by a number. Then you need to see which food item was chosen using a switch case statement. You can hard-code this in your program as say:
101 - Vada Pav
121 - Bhaji Pav
212 - Misal Pav
312 - Bhurji Pav
434 - Usal Pav

But, computer does not care about this. You could have 0,1,2,3,4 ... etc ,, each number representing one food item. This will normalize this and would be good thing. But it makes it harder to remember which food the number 3 stands for. Does 3 stands misal Pav or Bhurji Pav?

To make this type of scenarios easier, we can use an enum as follows. Consider the file enumFile.ts with the following content:

enum foodItem{
VadaPav,
BhajiPav,
MisalPav,
BhurjiPav,
UsalPav
}

let myVadaPav:foodItem = foodItem.VadaPav;
console.log("enum value of myVadaPav = "+myVadaPav);

let myBhajiPav:foodItem = foodItem.BhajiPav;
console.log("enum value of myBhajiPav = "+myBhajiPav);

let myMisalPav:foodItem = foodItem.MisalPav;
console.log("enum value of myMisalPav = "+myMisalPav);

let myBhurjiPav:foodItem = foodItem.BhurjiPav;
console.log("enum value of myBhurjiPav = "+myBhurjiPav);

let myUsalPav:foodItem = foodItem.UsalPav;
console.log("enum value of myUsalPav = "+myUsalPav);

Now let us compile the file:

$ tsc enumFile.ts
$

Now, In the browser console, we can see the following output:

enumFile.js:10 enum value of myVadaPav = 0
enumFile.js:12 enum value of myBhajiPav = 1
enumFile.js:14 enum value of myMisalPav = 2
enumFile.js:16 enum value of myBhurjiPav = 3
enumFile.js:18 enum value of myUsalPav = 4

We don't see the name of the food items but only the numbers in the console. This is because behind the scenes numbers are assigned to the food items automatically.

enum foodItem{
VadaPav, // 0
BhajiPav, // 1
MisalPav, // 2
BhurjiPav, // 3
UsalPav // 4
}

The first food item has received the number 0
the second food item has received the number 1 and so on...

Now, there could be some applications where we want to overwrite the default values created by enum. Say, instead at starting at 0, I want to start at 1000. For this, let us just assign the first value in enum to 1000.

enum foodItem{
VadaPav = 1000, // 0
BhajiPav, // 1
MisalPav, // 2
BhurjiPav, // 3
UsalPav // 4
}

let myVadaPav:foodItem = foodItem.VadaPav;
console.log("enum value of myVadaPav = "+myVadaPav);

let myBhajiPav:foodItem = foodItem.BhajiPav;
console.log("enum value of myBhajiPav = "+myBhajiPav);

let myMisalPav:foodItem = foodItem.MisalPav;
console.log("enum value of myMisalPav = "+myMisalPav);

let myBhurjiPav:foodItem = foodItem.BhurjiPav;
console.log("enum value of myBhurjiPav = "+myBhurjiPav);

let myUsalPav:foodItem = foodItem.UsalPav;
console.log("enum value of myUsalPav = "+myUsalPav);

Console Output:

enumFile.js:10 enum value of myVadaPav = 1000
enumFile.js:12 enum value of myBhajiPav = 1001
enumFile.js:14 enum value of myMisalPav = 1002
enumFile.js:16 enum value of myBhurjiPav = 1003
enumFile.js:18 enum value of myUsalPav = 1004


This gives us the idea to modify enums.


Reference:



TypeScript - DataTypes - Tuples

In the array world, we have a new type in TypeScript which is not available in JavaScript - Tuples. Tuples are arrays with fixed items in it. The values in tuples can be of different types. Tuples are a heterogeneous collection of values.

Let us say I want to store the count of Item which I wish to get for my Birthday.
let myBirthdayItem = ["Vada Pav", 99];

Now, if I am certain that this array will always have this format. That is, first item is a string and the second item is a number. Then I can inform TypeScript about this:
let myBirthdayItem: [string,number] = ["Vada Pav", 99];

I can specify it like this. But, now, if I reverse the order of the values.
let myBirthdayItem: [string,number] = [99,"Vada Pav"];

and on compiling, I receive the following error:

$ tsc arraysFile.ts
arraysFile.ts:8:40 - error TS2322: Type 'number' is not assignable to type 'string'.

8 let myBirthdayItem: [string,number] = [99,"Vada Pav"];
                                         ~~

arraysFile.ts:8:43 - error TS2322: Type 'string' is not assignable to type 'number'.

8 let myBirthdayItem: [string,number] = [99,"Vada Pav"];
                                            ~~~~~~~~~~

... this is because in a Tuple - order is important. The tuple has to have exactly the same format. 

To correct this issue, we must revert the order.



Reference:



Practice at:



TypeScript - DataTypes - Arrays

Arrays are a bit more advanced types. Consider the following TypeScript code in a file arraysFile.ts

let myGames = ["cricket","football"];
console.log("myGames[0] = "+myGames[0]);


Compiling the file: 
$ tsc arraysFile.ts

This will create a corresponding JavaScript:

$ ls -l arraysFile.*
-rw-r--r-- 1 ubuntu ubuntu 82 Oct 27 16:21 arraysFile.js
-rw-rw-r-- 1 ubuntu ubuntu 78 Oct 27 16:21 arraysFile.ts

We will include it corresponding JavaScript in our index.html as follows:
<script src="./arraysFile.js"> </script>


Now on opening the browser we can find - in the console:
myGames[0] = cricket

Of course, this is not eye-catching.  Now let us check what DataType does this myGames variable have:
console.log("typeof(myGames) = "+typeof(myGames));

Now, if we compile our code and check the output in browser Console:
typeof(myGames) = object

We see it is of object type. This is not eye-catching either. This is because an array is of type - object.  Now, let us try to assign number to myGames array variable.
myGames = [100];

Now let us compile:

$ tsc arraysFile.ts
arraysFile.ts:4:12 - error TS2322: Type 'number' is not assignable to type 'string'.

4 myGames = [100];
             ~~~



We have received this error that array of type number is not assignable to array of type string. Now, this is eye-catching if we think it in terms of JavaScript. But, since, this is TypeScript code - it is tobe expected. TypeScript has inferred the types of variables automatically. Since, we have initialized the variable myGames to an array of string, hence, TypeScript thinks that myGames should only be an array of type string.  So, if we assign it to an array of numbers - we therefore get an error. Now, if we change this to type string.
myGames = ["100"];

We are able to recompile it without any issues:
$ tsc arraysFile.ts
$

We can override this type checking by asssigning the myGames variable to be of type any array.

let myGames: any[] = ["cricket","football"];
console.log("myGames[0] = "+myGames[0]);
console.log("typeof(myGames) = "+typeof(myGames));
myGames = [100];
console.log("myGames == "+myGames);


Now, we are able to compile this file without any issues.

tsc arraysFile.ts
$

This is because, now I am overwriting the type of array which the TypeScript infers. But, it still have to be an array though. If I set the myGames to only 100.

myGames = 100;

On compiling, I receive the following error:

$ tsc arraysFile.ts
arraysFile.ts:6:1 - error TS2322: Type '100' is not assignable to type 'any[]'.

6 myGames = 100;
  ~~~~~~~



This is because, TypeScript is still expecting myGames variable to be of type array as we have square brackets after the keyword any[].
let myGames: any[] = ["cricket","football"];


Tuesday, October 23, 2018

JavaScript - The four pillars of object oriented programming

Object oriented programming consists of four key concepts:
  • Encapsulation
  • Inheritance
  • Abstraction
  • Polymorphism
Before object-oriented programming we had procedural programming which divided a program into numerous functions. Basically, data was stored in variables and functions operated on that data. The problem occurs as the programs grow. This is when it becomes difficult to manage as the number of functions keep growing. This can lead to spaghetti code - due to inter-dependency between different pieces of code. To solve this problem, object-oriented programming was created.

object-oriented programming:
In this style of programming we combine a group of functions and variables into a single unit. This unit is called as an object. The variables contained in the object are called properties and functions are called methods.

variables == properties
functions == methods

Consider the example of Procedural Programming to convert the temperature units from Celsius to Fahrenheit.
let celsiusTemp = 36;
let multiplier = 9/5;
let adder = 32;

function getFahrenheit(celsiusTemp, multiplier, adder){
  return ( celsiusTemp * multiplier) + adder ;
}

let fahrenheitTemp = getFahrenheit(celsiusTemp, multiplier, adder);

console.log(celsiusTemp+" Celsius = "+fahrenheitTemp+" Fahrenheit");

Output:
"36 Celsius = 96.8 Fahrenheit"
This kind of implementation is called procedural programming. The variables and functions here are decoupled - that is variables are on one side and functions are on other side.

We can rewrite the above example so that it follows the object oriented paradigm:
let temperature = {
   celsiusTemp : 36,
   multiplier : 9/5,
   adder : 32,
   getFahrenheit: function (){
    return ( this.celsiusTemp * this.multiplier) + this.adder ;
  }
};

let fahrenheitTemp = temperature.getFahrenheit();

console.log(temperature.celsiusTemp+" Celsius = "+fahrenheitTemp+" Fahrenheit");

Output:
"36 Celsius = 96.8 Fahrenheit"
We have created the temperature object with 3 properties:

  • celsiusTemp
  • multiplier
  • adder


and a method:

  • getFahrenheit


Now is this better? Look at the getFahrenheit method. This method has no parameters. In contrast, the procedural counterpart of it has 3 parameters. Since, the properties and the methods are related, therefore, they are part of a single unit. One of the identifying mark of procedural code is a function with many parameters. In a object oriented way of writing the code, the functions aka methods end up having less input parameters. As per the clean code practices defined by Robert C Martin:

"Best functions are those which have no parameters"

.... this covers the encapsulation part of object oriented programming.


Abstraction:

Think of the case of truck driver. The driver needs to know only how to drive the truck. He must know, how to press the brakes, accelerator pedal, change the clutch and move the steering wheel. He does not need to know about the internal workings of the engine of the truck. This is abstraction in practice. We can use the same technique when implementing objects. We can hide some of the properties and methods from the outside.




The benefits include:

  • Interface becomes simpler. 
  • Impact of change is reduced: For example: if we remove a method from a object, it will not affect rest of the code as only the object can use the method.



Inheritance:
This is a mechanism which allows us to eliminate redundant code. Consider HTML elements:

  • Textboxes
  • Drop-down lists
  • Check boxes

.. and so on. They have a few things in common. They should have properties like:

  • hidden
  • innerHTML

and methods like:

  • click()
  • focus()

Instead of redefining, these methods repeatedly in each of the methods - we can define once in a generic object and then the other objects can inherit this properties and methods.




Polymorphism:

  • Poly = many
  • morph = forms


In object-oriented programming, poloymorphism allows us to get rid of long switch-case statements or if-else statements. Consider our HTML elements example above. All the methods (click and focus) are common to the elements textboxes, checkboxes and dropdown. But the way in which the methods work may be different. Basically, the method behaves differently depending on the type of the object calling it.

Summarizing the benefits of object-oriented programming:
Encapsulation: Group releated variables and functions together. This helps to reduce complexity and increases reusability.
Abstraction: Hide the inner details and the complexity. Show only the essentials.
Inheritance: Eliminate redundant code.
Polymorphism: Helps to refactor ugly, switch case statements.


Practice at:




Thursday, October 11, 2018

TypeScript - Basics of Types

The language - TypeScript has received name because of its feature: Types.

The questions which come up next are:
  • Which types are available?
  • What are the benefits of using types?
  • How can we use these types provided?
  • Since types are available in JavaScript itself, then why do we need TypeScript?
Let us answer the last question first - why do we need TypeScript? The main difference is JavaScript is dynamic typed language. Whereas, TypeScript is static typed.

Example:

String Error Test:
Say, I create a file myName.ts with the following lines:

let myName = "Sashank";
myName = 34;
console.log(myName);

Now, if I try to compile the file. The compiler throws me the following error:
$ tsc myName.ts
myName.ts:2:1 - error TS2322: Type '34' is not assignable to type 'string'.

2 myName = 34;
  ~~~~~~
Numeric Error Test:
Now, let us consider the case where we create a numeric datatype and assign a string to it.

let varAge = 34;
varAge = "Sashank";
console.log(varAge);

$ tsc varAge.ts
varAge.ts:2:1 - error TS2322: Type '"Sashank"' is not assignable to type 'number'.

2 varAge = "Sashank";
  ~~~~~~



Boolean error Test:
Let us consider the boolean type in JavaScript. A boolean variable can hold a true or a false. Let us create a file hasFood.ts

let hasFood = true;
hasFood = "true";
console.log(hasFood);

Now, if I try to compile - a error is returned.

$ tsc hasFood.ts
hasFood.ts:2:1 - error TS2322: Type '"true"' is not assignable to type 'boolean'.

2 hasFood = "true";
  ~~~~~~~


This error has happened because, we tried to assign a string value to a Boolean variable.

Any Type - no error:

Consider our file myAnyType.ts. Now, if I do not assign to the variable at declaration time. Then, we can assign any type of value to this variable because TypeScript creates the variable of type Any. This is a special type of variable.

let myAnyType;
myAnyType = "london";
myAnyType = 34
myAnyType = true;
console.log(myAnyType);

Hence, on compilation, there is no error received:

$ tsc myAnyType.ts
$

This is the same behavior as we experience in JavaScript. So, this is not utilizing the power of TypeScript. We can assign a type to the declared variable without assigning it a value.

let myAnyType:number;
myAnyType = "london";
myAnyType = 34
myAnyType = true;
console.log(myAnyType);

Now, we will receive an error at the time of compilation as follows:

$ tsc myAnyType.ts
myAnyType.ts:2:1 - error TS2322: Type '"london"' is not assignable to type 'number'.

2 myAnyType = "london";
  ~~~~~~~~~

myAnyType.ts:4:1 - error TS2322: Type 'true' is not assignable to type 'number'.

4 myAnyType = true;
  ~~~~~~~~~



This is the explicit way of assigning value to a TypeScript variable. With this, we have answered all the questions we had asked at the beginning of our post.

Reference:

TypeScript - Setting up our project folder

Let us setup our project folder by referring to:

Before starting our project, our project folder (my-typescript-project-02) looks like this:
$ ls -l
total 8
-rw-r--r-- 1 ubuntu ubuntu 223 Oct 10 10:23 index.html
-rw-r--r-- 1 ubuntu ubuntu 390 Oct 10 10:17 script.ts


Now, let us try to setup our project folder so that we can reuse it. For this, let us put our project in the control of npm. Now in the command line type and select the defaults by pressing enter at the prompt:
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (my-typescript-project-02) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /home/ubuntu/Documents/my-foundation-project/my-typescript-project-02/package.json:

{
  "name": "my-typescript-project-02",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this ok? (yes) 
$

This will create the package.json file.

$ ls -l
total 12
-rw-r--r-- 1 ubuntu ubuntu 223 Oct 10 10:23 index.html
-rw-r--r-- 1 ubuntu ubuntu 220 Oct 11 09:18 package.json
-rw-r--r-- 1 ubuntu ubuntu 390 Oct 10 10:17 script.ts

We can check the contents of package.json. It is as follows:

$ more package.json
{
  "name": "my-typescript-project-02",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Now, let us install the lite-server using npm:
$ npm install lite-server --save-dev
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN my-typescript-project-02@1.0.0 No description
npm WARN my-typescript-project-02@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ lite-server@2.4.0
added 342 packages in 13.107s
Now, if you check the package.json again. We can see that lite-server is added as a dependency to this file:

{
"name": "my-typescript-project-02",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"lite-server": "^2.4.0"
}
}


Now since we want our lite-server to start and serve-up the pages in this folder. Let us add the following line to the scripts section of the package.json file:

"start": "lite-server"

Now, the scripts section of the package.json looks like this:

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "lite-server"
},


What will happen by adding this line is - when I type:

$ npm start

> my-typescript-project-02@1.0.0 start /home/shree/Documents/my-foundation-project/my-typescript-project-02

> lite-server

Did not detect a `bs-config.json` or `bs-config.js` override file. Using lite-server defaults...

** browser-sync config **
{ injectChanges: false,
  files: [ './**/*.{html,htm,css,js}' ],
  watchOptions: { ignored: 'node_modules' },
  server: { baseDir: './', middleware: [ [Function], [Function] ] } }
[Browsersync] Access URLs:
 ------------------------------------
       Local: http://localhost:3000
    External: http://10.12.60.32:3000
 ------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 ------------------------------------
[Browsersync] Serving files from: ./
[Browsersync] Watching files...
18.10.11 09:42:03 200 GET /index.html
18.10.11 09:42:03 404 GET /script.js
18.10.11 09:42:04 404 GET /favicon.ico


This starts the lite-server along with it. It will open a new tab in the default browser and will access the page: http://localhost:3000/

.. and our index.html file is served at this location. Now, let us type: Hello World in the body of the index.html

<body>
Hello World!
<script src="./script.js"></script>
</body>




We can see that Hello World message is reloaded in the browser tab - without me having to manually reload the page.





This is very convenient.

Now, we can compile the TypeScript file using the command.

tsc <<file-name>>

But, consider a situation where there are numerous TypeScript file and you want to compile all of them at once. For this type the following command at the prompt:

$ tsc --init
message TS6071: Successfully created a tsconfig.json file.


With this this folder comes under the control of TypeScript transpiler. This has created a file tsconfig.json. Now we have the following files in our project folder:

$ ls -l
total 152
-rw-r--r--   1 ubuntu ubuntu    235 Oct 11 09:46 index.html
drwxr-xr-x 269 ubuntu ubuntu  12288 Oct 11 09:31 node_modules
-rw-r--r--   1 ubuntu ubuntu    304 Oct 11 09:41 package.json
-rw-r--r--   1 ubuntu ubuntu 119604 Oct 11 09:31 package-lock.json
-rw-r--r--   1 ubuntu ubuntu    390 Oct 10 10:17 script.ts
-rw-r--r--   1 ubuntu ubuntu   5328 Oct 11 09:50 tsconfig.json


This tells TypeScript compiler that this project is our TypeScript project and to compile all the TypeScript files whenever we type tsc at the prompt:

$ tsc
$ ls -l
total 156
-rw-r--r--   1 ubuntu ubuntu    235 Oct 11 09:46 index.html
drwxr-xr-x 269 ubuntu ubuntu  12288 Oct 11 09:31 node_modules
-rw-r--r--   1 ubuntu ubuntu    304 Oct 11 09:41 package.json
-rw-r--r--   1 ubuntu ubuntu 119604 Oct 11 09:31 package-lock.json
-rw-r--r--   1 ubuntu ubuntu    461 Oct 11 09:58 script.js
-rw-r--r--   1 ubuntu ubuntu    390 Oct 10 10:17 script.ts
-rw-r--r--   1 ubuntu ubuntu   5328 Oct 11 09:50 tsconfig.json



We can see that when we typed tsc at he prompt. It searched for all the TypeScript files and compiled them to JavaScript files. In our case, there is only one file.

Now, we can reload our browser tab and check.