The Angular Series - TypeScript In A Nutshell - Part Two

Introduction and Background

Today, we’ll cover many concepts of TypeScript in depth. If you’ve not read my previous article of Angular series, here is the link

Go ahead and read this article. And then, start exploring TypeScript. Let’s start our journey.

What is TypeScript?

TypeScript is nothing but a superset of JavaScript. It means that everything we can do with JS, we can also develop through TypeScript. But TypeScript has most of the features that JS didn’t have supported in any browser. For example,

  • TypeScript has the concept of strong typing. As we already know that in different programming languages like in C# and Java, when we make the datatype of any variable then this type can’t be changed and we can debug the program very easily if there is any kind of exception.

Similarly, in TypeScript, we declare the type of any variable optionally but if we declare it with a specific type, we can debug our application very easily when something goes wrong.

  • Typescript also brings with quite a bunch of features of object-oriented programming. We’ve missed these OO features in JavaScript for a long time. Now, we have the concepts of classes, interfaces, constructors, access modifiers, fields, properties, generics and so on.
  • Another beautiful feature of TypeScript is we can catch the error at compile time instead of runtime. But it doesn’t mean we can catch all kinds of errors but a lot of errors we can catch.

So there is a compilation of steps involved and when we compile our TypeScript code, we can catch the errors and resolve them before deploying our application.

  • If we’re using TypeScript, then we’ve some awesome tools that we can use in our application like IntelliSense in code editor etc.

Any valid and correct Javascript code also has the valid Typescript code. Most important point is browsers doesn’t understand the TypeScript itself. So we need to compile our TypeScript code into javascript. So this is the part of our application building, whenever we build the application transcript compiler comes into play and compile our TypeScript code into javascript code to understand the browser.

Angular

First Typescript Program

Here we’ll explore how to install TypeScript and how to write the first program using TypeScript. Now open the Node.js cmd (Run as Administrator) or open the integrated terminal in Visual Studio Code and write the below command it is up to your choice.

We already know the pattern of writing the commands to install the package.

npm install –g packagename

-g is for to install the package globally.

Angular

Here, we’ve installed the latest version of TypeScript which is 2.8.3

Now, if you want to know the compiler version of typescript, then write here in VS Code terminal.

tsc –version

Angular

Now let’s make a transcript file and start coding but before getting started let’s make a new folder and make a new file in it.

Angular

This is how VS Code Terminal works actually Windows Powershell commands are working at the backend.

We see “code filename.ext” is used to create the file and open it and “code .” is used to open the current project in which directory you’re executing this command.

Here we’ve created “main.ts” file. As we already know that any valid javascript has valid TypeScript. Here in this file, we’ll write some plain javascript code and all the valid javascript code has valid TypeScript code.

Now we’ll compile the TypeScript code. So, first of all, make sure your directory where you’ve the TypeScript file and compile it,

TypeScript Code Compilation Command:

PS > tsc main.ts

Angular

And if we directly build the angular project with “ng serve” then we don’t have to do it manually, angular automatically calls the TypeScript compiler and compiles the code under the hood.

Now let’s open “main.js” file and run it and show the output in terminal.

PS > code main.js

PS > node main.js

Angular

Look it is exactly the same code we wrote in TypeScript file but now it is a javascript file. So the results are all javascript code is also valid for TypeScript code.

Declaring Variables

Let’s discuss some specific feature of Typescript that doesn’t have in javascript. Yes, we’re talking about TypeScript strong typing. Here, we’ve 2 ways to declare the variable.

  • We can use “var” keyword like we do in javascript.
  • We can use “let” keyword.

We already know that javascript has a few different versions, we have:

ES5 (EcmaScript 5)

supported by all browsers. We’ve been using it for a long time.

ES6 (2015)

It is the newer version and it was introduced in 2015. And here the EcmaScript team that extended javascript decided to use year number instead of the version number. Here, “let” keyword was introduced.

  • ES2016
  • ES2017

And then these new versions became introduced with the year name.

Let me tell you the difference between var and let, write some code in “main.ts” file. Here in the below image I’m compiling my typescript code and run the javascript code in a single statement in the terminal.

And one important thing; make sure you’ve saved the file on writing the code in TypeScript file otherwise you’ll see the previously compiled code result.

Angular

Look here it is valid and showing us the result with a digit number. And we already knew that the variable is not accessible outside of the loop.

Now try it with let, look I’ve not saved my file yet but TypeScript knows at compile time that it can’t be possible, your colorful file names become red and message you about something wrong.

Angular

Here 'i' is outside of the scope. And if you hover the mouse on "i" you’ll see the message that it doesn’t find the i variable.

Let’s save the file and remove our last built main.js

PS > rm main.js

Angular

Look we’ve removed the file. Now compile the TypeScript file, and here we’ll see the error in the console or in terminal.

Angular

And we’ve generated the compiled js file with a bug as you can see in the above image. Typescript compiler generates it for us -- even our TypeScriptfile has an error. Let’s look what we have in this main.js.

PS > code main.js

Angular

As we can see here our TypeScript file was showing us an error but here the code is compiled with var, actually, TypeScript code is by default compiled into ES5 which is supported by all browsers. And ES5 doesn’t have let keyword that’s why it is using var keyword. And this is perfectly valid javascript code which is generated in main.js and if we simply go into the terminal and run this main.js file, we’ll see the same results as we see before.

Angular

So the conclusion is TypeScript compiler just reports this error at the compile time. But it is still generating the valid JavaScript code. And now, we’ll always use let keyword in the next examples although it is generating the valid javascript at least we can catch the errors at compile time.

Types

Here we’ll explore different types which we have in TypeScript.

Let’s start with creating the integer number data type variable and then again assign that variable a string. Here we’ll see the error message if we hover the mouse on the variable.

Angular

But we can perfectly do this in javascript because in Javascript we can change the type of variables on the fly but in TypeScript, we get the compilation error. Now once again, we can also compile this using TypeScript compiler and we’ll surely get the valid javascript code as we do earlier. But although it will generate the valid javascript that code can break in future because might be we use this countNumber variable somewhere else in the application like in the loop. So our program will break at the runtime.

What if we declare the variable without initialization. Let’s look at this type.

Angular

We can see here the variable type is like we have the variable in javascript. So here we can do some tricky things.

Angular

Look everything is happening there and the compiler isn’t reporting it actually because it doesn’t know about the type at declaration.

The solution to this kind of problem is we use type annotations, we declare the type of the variable in the first statement and then if we try to initialize a different type of value then we’ll see the compile time error.

Angular

Here in TypeScript, we have different kinds of types. 

  1. let a: number;      // numeric and floating point numbers  
  2. let b: boolean;     // true or false  
  3. let c: string;          // string datatype  
  4. let d: any;         // We’ve already experienced with it before.  
  5. let e: number[];        // array  

Now let’s suppose we want to initialize the variable at the declaration time as well.

  1. let isAvailable: Boolean = true;  
  2. let marks: number = 530;  

Typescript also uses the template strings. Template strings are surrounded with backticks (``) and we use them with ${} syntax like we do in C# (string interpolation).

  1. let fullName: string = `usama`;  
  2. let position: number = 1;  
  3. let sentence: string = `Hello, World! My name is ${fullName} and I’ve got ${position + 1} in exams`; 

We can define the dimensions of array but it is optional.

  1. let f: number[] = number[1, 2, 3];  
  2. let g: any[] = any[1, true, ‘a’, false];  

Of course these techniques aren’t recommended but we’re discussing them here just to know about the things.

As we have the generics in C#, we have the generics in Typescript as well. We can declare the array with generics as well.

  1. let list: Array<number> = [1, 2, 3];  

We also have enums in TypeScript, enums are used to define the constants. We put all the constants in a container. In old Javascript language, we explicitly define the constants like,

  1. const ColorRed = 0;  
  2. const ColorGreen = 1;  
  3. const ColorBlue = 2;  

But now in TypeScript we can define the enum as.

  1. enum NameOfEnum { elements }  
  2. enum Color { Red, Green, Blue }  

Angular

Look we see the intellisense in TypeScript, it helps to write the code so fast. We don’t any need to remember things. We already know that enums are 0 based by default and each next value will be incremented with the next value. So we don’t any need to set the explicit value in enum. But the best practice is to explicitly assign the values to the elements. Because if you’re using the old enum in your application and then in the future you add one more element inside the enum elements then the order of elements and their values will become changed. So the best approach is to assign the explicit value and assign the 1 value to the first element of enum because if your enum is 0 based and you’re working with database then you might face the errors in your application.

  1. enum Color { Red = 1, Green = 2, Purple = 4, Blue = 3 }  

Now let’s compile our TypeScript file and watch how our TypeScript enum is render into the javascript.

PS (Take Care of File Folder Path) > tsc main.ts

Angular

You can see how complex our javascript code is which we compiled through our typescript code. That’s why developers love angular and TypeScript. The statement which we write in just one line is compiled into many lines in javascript. This is the major difference among both  TypeScript and javascript.

If we want to initialize a variable with any enum element, then we’ll declare the variable as,

  1. enum Color { Red, Green, Blue }  
  2. let c: Color = Color.Green;  

Destructuring

Another beautiful feature of ECMAScript 2015 that  is included in Typescript is destructuring. Let me share the example with you.

  1. let x = [50, 100];  
  2. let [e1, e2] = x;  
  3. console.log(e1);                // 50  
  4. console.log(e2);                // 100  

Under the hood, it creates the 2 different variables, e1 and e2, containing the values on x array 1st and 2nd index.

Spread

If you’re an expert oinJavascript then you’ll certainly know about these features of Javascript. Yes there is a concept of spread in javascript. Here we’ll implement spread in TypeScript. Actually it is opposite to the destructuring, let me share the example with you.

  1. let x = [5, 7];  
  2. let y = [3, 8];  
  3. let both = [9, x, y, 10];  

If we combine the array like this,

  1. console.log(both);                              // [9, [5, 7], [3, 8], 10]  

it will show like this in this format. But if we use the spread operator,

  1. let both = [9, …x, …y, 10];  

It will render our array in the original,

  1. console.log(both);              // [9, 5, 7, 3, 8, 10]  

You can see these three dots with name of variable (…x) is called spread. In destructuring we’re splitting the things, it allows us to spread an array into another array. We can even spread an object into another object.

Type Assertions

Let’s start by declaring the variable.

  1. let text = ‘usama’;         // Here Typescript know that ‘text’ is string.  
  2. text.   // Here we’ll see the intellisense full of methods.    We can perform any method on this type

Angular

Here intellisense guides us how to write the code. But sometimes TypeScript become confused about the type of the variable like if the variable declaration has ‘any’.

  1. let text;   // any  
  2. text = ‘usama’;  
  3. let found = text.   // Here you’ll not see the intellisense.  

Angular

As we can see we’re not getting any intellisense. And we can’t apply any method which we were implementing before. So in this scenario, we need to manually tell the TypeScript compiler the type of the variable. This is called type assertion.

There are 2 ways to make type assertion.

  • (<type>variable)
    Here we get all the methods and functions that we can implement upon the string type.

    Angular

  • The second method is to use the as keyword like we do in C#.
    (text as string).

    Angular

Keep in mind, type assertion doesn’t change the type of the variable at runtime. In fact it doesn’t restructure the variable in memory. It just helps us to behave a variable like a specific type.

Arrow Functions

It is also an important concept, in javascript we already know that how can we declare the function

  1. // Javascript method  
  2. let log = function (text) {  
  3.     console.log(text);  
  4. }  
  5. log(‘usama’);  
  6.   
  7. // Typescript method  

We don’t need any function keyword here. This is the technique we use do in C#. In C# we call this lambda expression and in TypeScript we call this arrow function. Yes it is exactly the same thing.

If the method body has only 1 statement, then we can also remove the curly braces as well and if there is only 1 parameter then we can remove the parenthesis of parameters. If there are multiple lines then we use curly braces and if there are multiple parameters then we must use the parenthesis enclosed parameters.

One more thing, always use double quote for string here. Otherwise you’ll see errors.

  1. let logMessage = message =>  console.log(message);  
  2. let logMessage1 = (message, recipient) => {  
  3.     console.log(“Hello” + message);  
  4.     console.log(“I\’m here” + recipient);  
  5. }  
  6. logMessage(“usama”);  
  7. logMessage1(“sweety”, “Usama”);  

But the best practice is always use the parameters in parenthesis to make it more readable.

And if we don’t have any parameter for our function then we’ll surely make the parenthesis empty and write our arrow function.

  1. let logMessage2 = () => console.log(“Hello, World!”);  

If we compile our arrow functions, let’s see how does it look like in javascript. But save the TypeScript file.

Angular

Interface

Let’s see how can we use custom types in typescript. Let’s suppose we’re working with a function who needs 2 points to draw something.

  1. let drawPoints = (x, y) => {  
  2.     // to do something  
  3. }  

But if there are multiple points and if we pass all the parameters to a function, then this would be a code smell. We always try to make our code clean.

  1. let drawPoints = (a, b, c, d, e, f, g, h) => {  
  2.     // ….  
  3. }  

Instead of passing all the parameters, we can pass a single object which has all these properties.

  1. let drawPoints = (point) => {  
  2.     // here point is the object  
  3. }  

And then we can call this function as.

  1. drawPoints({  
  2.     x: 5,  
  3.     y: 8,  
  4.     z: 9            // so on how much you need  
  5. });  

Now our code is much cleaner, but still there is a problem with this kind of logic. We can pass anything to the point object like.

  1. drawPoints({  
  2.     name: “Usama”,  
  3.     loves: “Azure”  
  4. });  

And if we already define the implementation of the points in arrow function and we’re passing different named parameters then surely our code will break at the runtime. So we need to limit the user to pass the specific named parameters.

Here we have 2 solutions to solve this problem.

Use inline annotation.
  1. let drawPoints = (point: { x: number, y: number }) => {  
  2. }  

Angular

It works fine for simple cases but let’s suppose we’re doing function overloading then we need to repeat the inline annotations again and again with the other functions as well. So in that scenario, we need to use ‘Interface’

Concepts are the same in every programming language, just the syntax changes. If you know the concept of interface because we use interface OO languages like in C#, Java then surely you’ve have an idea why interface is important.

Come in Typescript file and define interface. Defining interface is just like the defining the shape of the object.

  1. interface Point {  
  2.     x: number,  
  3.     y: number  
  4. }  

Now simplify the implementation of the function.

  1. let drawPoints = (point: Point) => {  
  2. }  

Now it is much cleaner and we can reuse this in multiple places. If you’re defining the custom types always use Pascal notation like we do here in our code. It helps you during development.

Here is my final main.ts file.

Angular

 

And my main.js file is which I compiled through my main.ts file.

Angular

In some programming languages, we always need to explicitly define the class with interface to implement the interface like in static programming languages. But as we know javascript itself and javascript family is a dynamic programming language. So, here we don’t any need to implement the interface explicitly. 

  1. interface Label {  
  2.     label: string;  
  3. }  
  4.   
  5. function printMessage(labelObj: Label) {  
  6.     console.log(labelObj.label);  
  7. }  
  8.   
  9. let myObj = { name: "Usama", label: "Hello, World!"};  
  10. printMessage(myObj);  

For more examples with different scenarios in Typescript’s interface, open this link. If you know OOP in C# or Java, you’ll get to the point that it is totally you already know. Just you’ve syntax changing here. Nothing is new.

Classes And Objects

Now we’ve seen how we can define the shape of the object but still there is a problem with this implementation. In OOP, we have the concept of cohesion which means that the things are related should be part of one unit. Everything that is in the block should be relevant to the block. Things are fully structured and relevant to each other. This is called cohesion.

Now look in the previous example, we made the interface and implemented it in the function. Here we violated the concept of cohesion. Although we can use interface in that manner, I’m not telling you that you should avoid from interface and go ahead with classes. I’m just creating the scenario to make you understand the different concepts. Interface has its own benefits that we can never enjoy without interface. So interfaces are also important. Let’s suppose you’re using a utility library in your project then how will you use the object in the function. Certainly, the below code technique. So it is also important to know. 

  1. interface Point {  
  2.     x: number,  
  3.     y: number  
  4. }  
  5. let drawPoints = (point: Point) => {  
  6. }  

Here the Point should be highly related to the function, these should not be 2 separate things.

So the class is

“Properties And Methods That Are Highly Related.”

Yes I know it is my own created definition and if any reader of this article is experienced, surely he’ll kill me. But it is just for your understanding. This is not the proper definition of class.

In the above example we can’t move the function inside the interface because interfaces are purely for declarations, they can’t have implementation of anything. But we can also declare the function prototype in the interface.

  1. interface Point {  
  2.     x: number,  
  3.     y: number,  
  4.     draw: () => void     // no parameters return void  
  5. }  

As these properties and methods are the part of one code block, so we don’t any need to pass the parameters inside the method. That’s why draw method has no parameter. Now we can implement it somewhere else.

We were discussing the cohesion principal, we already knew that coupling and cohesion principle implements on the classes. So, we convert it into the class and follows the class syntax with a new example.

  1. class Vehicle {  
  2.     x: number;  
  3.     y: number;  
  4.     Drive() {  
  5.         // ….  
  6.     }  
  7.     CoveredDistance(distance: Vehicle) {  
  8.         // …..  
  9.     }  
  10. }  

Here we can see things are fully related to each other. When a function is part of a class, it is called method.

Now let’s create the object variable of this custom type.

  1. let car: Vehicle;  

Look we’re getting the intellisense for the available methods and properties.

Angular

Now let’s run the Drive method with this object variable. Compile and run the program but essentially save your TypeScript file prior.

Here we get the compile time error.

Angular

Look it is undefined. Actually in the above code we have just created the specific type ‘Vehicle’ variable. It is actually not allocating the space into the memory. So, we need to make it complete.

  1. let car: Vehicle = new Vehicle();  

As we can see we’re repeating the Vehicle 2 times, so we need to make our code clean.

  1. let car = new Vehicle();  

It is ok now. Here TypeScript compiler automatically knows from the initialization that caris the type of Vehicle

Now let’s compile, run main.js and check the type of ‘car’

Angular

Now look we’ve not even assigned the values to the properties and still it is compiled successfully. And if we console.log the properties in the Drive()

Angular

Now let’s initialize the x and y points. Now it is working successfully.

Angular

Keep in mind, Vehicle is the class and car is the object. And object is the instance of Class.

Constructors

Look here we have 3 lines to initialize the properties. This approach is not good. Constructor basically uses it to initialize the properties. Imagine if the class has a few more properties then surely you’ll be tired to initializing all the properties line by line.

  1. let car = new Vehicle();  
  2. car.x = 50;  
  3. car.y = 100;  

Let’s discuss the concept of constructor. Every class has a default constructor which is basically called when we create the instance of the class with the help of new Obj()

Angular

But let’s suppose we don’t know the constructor parameters and their patterns. In C#, Java other programming languages we’ve the default constructor as well but here in TypeScript, we don’t have the default constructor. So if we’re not providing the initial values we’ll be getting the error.

Angular

So in this kind of scenario, we need to make our parameters optional. And we can do it by using question mark (?).

In C# we can have multiple constructors but in TypeScript we can’t have multiple constructors.

That’s why we’re making it optional.

Angular

Now we’re not getting any compilation error.

Inheritance

In Typescript, we can also extend the implementation of any class just by inherit the base class with child class. Yes we can do in Typescript, this is the beauty of Javascript.

  1. class Vehicle {  
  2.     move(direction: string = “forward”) {  
  3.         console.log(`Vehicle is moving ${direction}`)  
  4.     }  
  5. }  
  6.   
  7. class Car extends Vehicle {  
  8.     numberOfSeats(number: int) {  
  9.         console.log(`Car has ${number} of seats`);  
  10.     }  
  11. }  
  12. let car = new Car();  
  13. car.numberOfSeats(4);  
  14. car.move(“forward”);  

Constructor Inheritance

Yes we can also make inheritance in constructors like we do in C# with the help of base(), here we use super()

  1. class Vehicle {  
  2.     private wheelers: number;  
  3.       
  4.     constructor(wheel: number) {   
  5.         this.wheelers = wheel;   
  6.         console.log(`Vehicle has ${this.wheelers} wheels`);  
  7.     }  
  8.       
  9.     move(direction: string = 'forward') {  
  10.         console.log(`Vehicle is moving ${direction}`)  
  11.     }  
  12. }  
  13.   
  14. class Car extends Vehicle {  
  15.     constructor(wheels: number) { super(wheels); }  
  16.     numberOfSeats(number: number) {  
  17.         console.log(`Car has ${number} of seats`);  
  18.     }  
  19.     move(direction: string) {  
  20.         super.move(direction);  
  21.     }  
  22. }  
  23.   
  24. class MotorBike extends Vehicle {  
  25.     constructor(wheels: number) { super(wheels); }  
  26.     numberOfSeats(number: number) {  
  27.         console.log(`MotorBike has ${number} of seats`);  
  28.     }  
  29.     move(direction: string) {  
  30.         super.move(direction);  
  31.     }  
  32. }  
  33.   
  34. let car = new Car(4);  
  35. let motorbike : Vehicle = new MotorBike(2);  
  36. car.move('backward');  
  37. motorbike.move('forward');  

We already knew that if the variable is of base type then we can make the child type object with this variable. This is the concept of OOP. Don’t be confused about the results, these are actually the simple objects of a simple classes. And here is the result.

Angular

Access Modifier

Look in the above example, still we can initialize the variable after creating object.

  1. let car = new Vehicle(50, 100);  
  2. car.x = 30;  
  3. car.y = 70;  

It is ok in our scenario, but we want to limit our properties to not be accessible outside of the class so here we need access modifiers. It reduces the chances of bugs.

We apply the access modifier on the member of the class to control the accessibility of class members.

In Typescript we have 3 access modifiers.

  • Public
  • Private
  • Protected

By default class all members are public, that’s why  we’re accessing  x and ywith the instance object as well. Let’s make our properties private and if we’re using x and y with the instance object then we’ll see compilation error.

  1. class Vehicle {  
  2.     private x: number;  
  3.     private y: number;  
  4.       
  5.     constructor(x?: number, y?: number) {  
  6.         this.x = x;  
  7.         this.y = y;  
  8.     }  
  9.   
  10.     Drive() {  
  11.         console.log('Initial Point is: ' + this.x +   
  12.         ' And Final Point is: ' + this.y);  
  13.     }  
  14. }  
  15.   
  16. let car = new Vehicle(50, 100);  
  17. car.Drive();  

Now let’s compile the code and open the main.js

Angular

Now let’s discuss a very beautiful feature in TypeScript as well. As you can see we’re making our code redundant by using (this.x, this.y) in the constructor. We can make our code clean by just simply prefixing it with private in constructor header and removing the redundant code.

  1. class Vehicle {  
  2.     constructor(private x?: number, private y?: number) {  
  3.     }  
  4.   
  5.     Drive() {  
  6.         console.log('Initial Point is: ' + this.x +   
  7.         ' And Final Point is: ' + this.y);  
  8.     }  
  9. }  
  10.   
  11. let car = new Vehicle(50, 100);  
  12. car.Drive();  

It will automatically create the private class member properties and initialize it like we do in constructor before. Now let’s verify it by generating its main.js

Angular

Yes it is looking the same. So TypeScript has a very beautiful feature with constructors. We can also make constructor parameters public, all it depends upon is our requirements.

We already know that protected number is only available in the derived class. So let’s make an experiment.

  1. class Vehicle {  
  2.     protected wheel: number;  
  3.       
  4.     constructor(wheel: number) {   
  5.         this.wheel = wheel;   
  6.         console.log(`Vehicle has ${this.wheel} wheels`);  
  7.     }  
  8. }  
  9.   
  10. class Car extends Vehicle {  
  11.     private name: string;  
  12.   
  13.     constructor(model: string, wheels: number) {  
  14.          super(wheels);   
  15.          this.name = model;  
  16.          console.log(`My Car is ${this.name} and it has ${this.wheel}`);  
  17.     }  
  18. }  
  19.   
  20. let car = new Car("Honda", 4);  

Look we can see this.wheelers can be accessible in the derived class.

This pointer

Do you know the concept of this pointer? This pointer contains the reference of its type. Look in the derived class we can use the variable of parent member because the member is protected in the parent class, and protected members are accessible in the derived class. And here we’re using this, it means Car class has the wheel field.

Properties

Now this implementation still has a tiny problem. We have constructor to initialize the fields. We have function to perform some custom operation and this operation can be anything. But we don’t have any type to read the value of the fields.

We have a few methods to return the value of the fields.

The first technique is:

  1. class Vehicle {  
  2.     constructor(private x?: number, private y?: number) {  
  3.     }  
  4.   
  5.     Drive() {  
  6.         console.log('Initial Point is: ' + this.x +   
  7.         ' And Final Point is: ' + this.y);  
  8.     }  
  9.   
  10.     getX() {  
  11.         return this.x;  
  12.     }  
  13. }  
  14.   
  15. let car = new Vehicle(50, 100);  
  16. console.log(car.getX());  
  17. car.Drive();  

The result of this code will be.

Angular

Now if we want to set the field value later on after creating the object and call its constructor even after initializing the variables. Then we use setter technique. These are the things all we do and all we know if you’re C# developer. So let’s add Setter in the class.

  1. class Vehicle {  
  2.     constructor(private x?: number, private y?: number) {  
  3.     }  
  4.   
  5.     Drive() {  
  6.         console.log('Initial Point is: ' + this.x +   
  7.         ' And Final Point is: ' + this.y);  
  8.     }  
  9.   
  10.     getX() {  
  11.         return this.x;  
  12.     }  
  13.   
  14.     setX(value) {  
  15.         if (value < 0) {  
  16.             throw new Error('Enter a valid value');  
  17.         }  
  18.         this.x = value;  
  19.     }  
  20. }  
  21.   
  22. let car = new Vehicle(50, 100);  
  23. car.setX(70);  
  24. console.log(car.getX());  

Now we can also set our field values outside of the class. Same scenario we do in C#, initially we were creating the getter and setter manually but later C# introduced the concept of properties.

Here we’ve made the getter setter code manually. Similarly now TypeScript also introduced some new feature, now we have get and set built-in keywords. Look the code below.

  1. class Vehicle {  
  2.     constructor(private x?: number, private y?: number) {  
  3.     }  
  4.   
  5.     Drive() {  
  6.         console.log('Initial Point is: ' + this.x +   
  7.         ' And Final Point is: ' + this.y);  
  8.     }  
  9.   
  10.     get X() {  
  11.         return this.x;  
  12.     }  
  13.   
  14.     set X(value) {  
  15.         if (value < 0) {  
  16.             throw new Error('Enter a valid value');  
  17.         }  
  18.         this.x = value;  
  19.     }  
  20. }  
  21.   
  22. let car = new Vehicle(50, 100);  
  23. car.X = 80;  
  24. console.log(car.X);  

If you’re an experienced developer then you surely know that if we want to make the property as readonly then we’ll just use getter, we don’t implement or write the code for setter. So comment out the setter code in our class to make the property as readonly.

Angular

Look here we’re getting the error on initializing the readonly property.

Modules

Now I’ve simplified my Vehicle class, now I’ve simple constructor and a method. This is a very simple program.

  1. class Vehicle {  
  2.     constructor(private x?: number, private y?: number) {  
  3.     }  
  4.   
  5.     Drive() {  
  6.         console.log('Initial Point is: ' + this.x +   
  7.         ' And Final Point is: ' + this.y);  
  8.     }  
  9. }  
  10.   
  11. let car = new Vehicle(50, 100);  
  12. car.Drive();   

It has only  1 file but if in the real world, application consists of hundreds of files. We don’t write all the code in just one file. So here we’ll learn how to depreciate the code in files.

First of all we move the definition of Vehicle class in a file (Vehicle.ts)

PS > code Vehicle.ts

And now move the Vehicle class from main.ts to Vehicle.ts. This is the concept we called Modules. In Typescript, we think each file as a Module. So in this program, we can say we’ve 2 modules but not accurately. In Vehicle.ts file, we can’t access the Vehicle class outside of the file. This file has its own scope. Look here we’re getting the error.

Angular

But if we want to access this class outside of this file we need to export this class. Just prefixing the class with export keyword.

  1. export class Vehicle {  
  2.     constructor(private x?: number, private y?: number) {  
  3.     }  
  4.   
  5.     Drive() {  
  6.         console.log('Initial Point is: ' + this.x +   
  7.         ' And Final Point is: ' + this.y);  
  8.     }  
  9. }  

Now this file considered as a module, save the export file. Now we need to import this file in main.ts as well. So,

  1. import { comma separated class names if multiple (class name) } from ‘relative path (name of module)’;  
  2. import { Vehicle } from './Vehicle';  
  3. let car = new Vehicle(50, 100);  
  4. car.Drive();   

(./) is because both files (main.ts and Vehicle.ts) are in the same folder. Don’t add the extension name with file otherwise you’ll see the compilation error.

There are a lot more thingsthat can be discussed in modularity, but the things which we’ve discussed are quite enough to start the angular project.

Keep in mind angular modules are defined in a different way, we don’t add the relative path in angular module cases. When we define the angular modules and import it into our TypeScript file, we just use the library names as a module names like,

  1. import { Vehicle } from ‘@angular/core’;  

In Typescript, we devide our program into multiple files. In each file we export one or more types, these types can be classes, functions, simple variables and objects and where we need to use these types we need to import them first. When we have an import and export statement on top of the file, that file is a module in TypeScript’s point of view. We also have the concept of module in angular but it is little bit different, they are not about the organization of code in different files. They are about organization of your application into smaller functional areas.

Angular

Conclusion

Here we’ve covered a lot of stuff about Typescript. But everything is not complete, but if you’ve read this article then you can move on with a project. And if you want to learn more about TypeScript, then the best source is its documentation.

Recently Microsoft has introduced new updates in Typescript. If you want to know about these updates, here is the link.


Similar Articles