Unit 4 MSD M TS
Unit 4 MSD M TS
Typescript
About TypeScript
Implementing a JavaScript-based application is more error-prone as it supports dynamic typing and
supports non-strict mode with global variables.
TypeScript makes such implementations easy, as it supports static typing and structured code with the
help of modules and object-oriented concepts.
This course introduces various features and programming constructs of TypeScript which enables you
to develop a highly structured, less error-prone JavaScript code using TypeScript features.
Pitfalls of JavaScript
Dynamic Typing: It decides the data type of the variable dynamically at run time.
Interpreted Language: It is a language in which the code instructions are executed directly
without prior compilation to machine-language instructions.
Minimal Object Oriented support: Object-Oriented Programming (OOP) is a programming
methodology based on the concept of objects. Object-Oriented concepts like classes,
encapsulation, inheritance help in the readability and reusability of the code.
Minimal IDE support: Integrated Development Environment (IDE) is a software application that
provides all necessary options like code refactoring, intelliSense support, debugging support to
software programmers for software development.
Dynamic Typing
Consider the below JavaScript function:
function calculateTotalPrice(quantity, unitPrice) {
return quantity * unitPrice;
}
We can invoke this function using the below code:
console.log(calculateTotalPrice(3, "500"));
Since JavaScript is dynamically typed, we can invoke the above function using the below code as well.
console.log(calculateTotalPrice('three', "500"));
Even though the above code will not throw any error, it will return NaN as output, since the expected
number type value is not passed to the quantity argument of the calculateTotalPrice function.
To avoid the above runtime error we can use static typing in TypeScript, wherein we will add data type to
the function argument while defining it. Consider the same JavaScript function written using TypeScript
as below:
The disadvantage is most of the errors can be identified only at run time.
This can be overcome by using TypeScript which will be transpiled to JavaScript and most of the
errors will be fixed during the transpilation time itself.
Therefore, TypeScript saves the application development time for a JavaScript developer.
Minimal Object Oriented Support
The equivalent Typescript code is as below:
class Product{
protected productId:number;
}
class Gadget extends Product{
getProduct():void{
}
}
You can observe from the above code that:
The readability of the JavaScript code is minimal.
Abstraction is done using closures or self-invoking functions wherein the number of lines of code
is more compared to public, private, protected access modifiers.
Classes are created using a constructor function, which leads to confusion compared to using the
class keyword.
Javascript supports OOP through prototypal inheritance which is complex for people with
classical inheritance background to understand.
In addition to that TypeScript also supports interface and generic concepts which is not supported by
JavaScript.
Minimal IDE Support
A few IDEs have code refactoring, IntelliSense support for JavaScript application development.
IntelliSense support helps in writing the code quickly.
Refactoring support helps in changing the variable or function names throughout the application
quickly.
Most of the IDEs has good support for TypeScript, some are listed below:
Visual Studio with versions 2015, 2013, and so on
Sublime Text
Atom
Eclipse
Emacs
WebStorm
Vim
Why TypeScript?
JavaScript application development has become easier with the help of the following tools:
npm can be used to download packages
webpack can be used to manage the complexity of applications.
Babel can be used to fetch the latest features of the language.
Tools like rollup and uglifyjs can be used to optimize application payloads.
prettier and eslint can be used to uphold code with consistent style as well as quality.
IDE like Visual Studio Code with Node.js environment can be used to run JavaScript code
everywhere.
There is browser support challenge for the latest ES6 version of JavaScript. You can use ES6 transpilers
like Babel to address this.
TypeScript can be another preferred option which is a superset of JavaScript and transpiles to the
preferred version of JavaScript.
What is TypeScript?
TypeScript can be considered as a typed superset of JavaScript, that transpiles to JavaScript.
Transplier converts the source code of one programming language to the source code of another
programming language.
TypeScript makes the development of JavaScript more of a traditional object-oriented experience.
TypeScript is based on ECMAScript 6 and 7 proposals.
Any valid JavaScript is TypeScript.
Relationship between TypeScript and JavaScript
TypeScript implements EcmaScript specification. Apart from the EcmaScript specification,
TypeScript has its own features as well.
JavaScript also implements EcmaScript.
TypeScript code must be transpiled to JavaScript code to use it in an application.
From the above code, the TypeScript class Helloworld is converted to a self-invoking function in
JavaScript when transpiled.
You can use TypeScript's online playground editor to see how TypeScript gets converted into JavaScript.
Features of TypeScript
Static Typing: It adds static typing to JavaScript, due to which the readability of the code improves and
helps in finding more early compilation errors than run time errors.
Modules support: TypeScript provides an option to create modules to modularize the code for easy
maintenance. Modules help in making the application scalable.
Object-Oriented Programming: TypeScript supports Object-Oriented Programming features such as
class, encapsulation, interface, inheritance and so on which helps in creating highly structured and
reusable code.
Open Source: TypeScript is open source. The source code of TypeScript can be downloaded from
Github.
Cross-Platform: It works across the platform.
Tooling Support: TypeScript works extremely well with Sublime Text, Eclipse, and almost all major
IDEs compared to JavaScript.
Installing TypeScript
To install TypeScript, go to the official site of TypeScript ( http://www.typescriptlang.org/ ) and
follow the steps mentioned there to download TypeScript.
As mentioned on the official site, you need to install Node.js.
Install Node.js from the official site of Node.js ( https://nodejs.org/en/) or Software Center.
Open a Node.js command prompt and check whether node and npm are installed in your machine by
using "node -v " and "npm -v" commands.
npm is a command-line tool that comes along with Node.js installation with which you can download
node modules. TypeScript is also such a node module that can be installed using npm.
In the same Node.js command prompt, type the "npm i –g typescript" command to download the
TypeScript module from the repository.
On successful execution of above command, the TypeScript module will get downloaded under
folder C:\Users\<<username>>\AppData\Roaming\npm\node_modules\typescript as shown below.
To configure TypeScript with different IDEs. Here are some of the popular IDEs for working with
TypeScript:
Visual Studio code
Eclipse IDE
Visual Studio 2015
First TypeScript Application
To start with the first application in TypeScript, create a file hello_typescript.ts under a folder. In the ts
file give a console.log statement and save it.
From the Node.js command prompt, navigate to the directory in which the ts file resides and compile the
ts file using the tsc command.
After compilation of the TypeScript file, the corresponding JavaScript file gets generated.
To run the generated JavaScript file, use the node command from the command line or include it in an
HTML page using the script tag and render it in the browser.
TypeScript Basics
Consider the below page of the Mobile Cart application. The information such as mobile phone
name, price, status on the availability of the mobile, discounts is displayed on the page. It also displays
different price ranges as GoldPlatinum, PinkGold, SilverTitanium.
Each of the information getting displayed has a specific type. For example, the price can only be numeric
and the mobile name can only be a string.
There should be a mechanism using which you can restrict the values being rendered on the page.
Sometimes it is preferred to have a text instead of numeric values to represent some information. For
example, on the above page instead of categorizing the mobiles based on their prices, you can prefer to
remember them as some text like GoldPlatinum, PinkGold, etc.
TypeScript is a static typed language that allows us to declare variables of various data types so that you
ensure only the desired type of data being used in the application.
Let us discuss declaring variables and basic data types supported by TypeScript.
Declaring Variables
Declaration of a variable is used to assign a data type and an identifier to a variable. Declaration of
variables in TypeScript is like JavaScript variable declaration.
Below are the three declaration types supported in TypeScript.
Data
Explanation
Type
Variable declared with this type would have function scope.
They can be re-assigned and re-defined.
var
When a variable declared outside the function, it would have global scope
and automatically attaches itself to the window object.
Variable declared with this type would have a block-level scope.
let
They can be re-assigned and cannot be redefined.
Variable declared with this type would have a block-level scope.
const
They can be neither re-assigned nor re-defined.
Problem with var declaration:
In the below code, you will observe a strange behavior of the variable count. You can access this variable
even outside the loop although it is defined inside the loop. This is due to the global scope nature of
the var data type declaration.
Output:
Some of the other problems with global scope variable are:
When the var declared variable is defined outside a function it is attached with the window
object which has only one instance.
This is a bad practice and causes an overridden of a variable when you try to use a third-party
library working with the same variable.
Generally, var variables have a function-scope and if they are not declared within a function, they
have a global scope.
To overcome this issue, in ES2015. JavaScript has introduced let and const as two new declaration types
and it is considered as standard because declaring variables by these two data types are safer
than declaring a variable using the var keyword.
Let us learn about these declarations.
Output:
Since the count variable is a block-scoped, it is not accessible outside the for loop hence results in the
error as not defined.
Difference between var and let Keyword
Capturing Variable in the loop
Variable declared using var keyword will have function scope. So, even if you declare a variable
using var inside a loop, it will have function scope.
In the below example, variable i has been declared inside the for loop using the var keyword, but it will
have the scope of the function. Thus, by the time setTimeout function executes, the value of i has already
reached 10.
Therefore, every invocation of setTimeout function gets the same value of i as 10.
Variable declared using let keyword will have block scope. Therefore, once the block is terminated, the
scope also is lost.
In the below example, variable i has been declared using let inside the for loop. So, its scope will be
limited to one iteration of the loop.
In this scenario, every invocation of the setTimeout function will get the value of i from that iteration
scope.
Difference between var and let Keyword
Redeclaring block-scoped variable:
The let declared variable cannot be redeclared within the same block.
The var declared variable can be redeclared within the same block.
Basic Types
Data type mentions the type of value assigned to a variable. It is used for variable declarations.
Since TypeScript supports static typing, the data type of the variable can be determined at the
compilation time itself.
There are variables of different types in TypeScript code based on the data type used while declaring the
variable.
boolean:
boolean is a data type that accepts only true or false as a value for the variable it is been declared.
In a shopping cart application, you can use a boolean type variable to check for the product availability,
to show/hide the product image, etc.
number:
number type represents numeric values. All TypeScript numbers are floating-point values.
In a shopping cart application, you can use number type to declare the Id of a product, price of a product,
etc.
string:
A string is used to assign textual values or template strings. String values are written in quotes – single or
double.
In a shopping cart application, you can use string type to declare variables like productName,
productType, etc.
Template strings are types of string value that can have multiple lines and embedded expressions. They
are surrounded by the backquote\backtick (`) character and embedded expressions of the form ${ expr }.
any:
any type is used to declare a variable whose type can be determined dynamically at runtime with the
value supplied to it. If no type annotation is mentioned while declaring the variable, any type will be
assigned by default.
In a shopping cart application, you can use any type to declare a variable like screenSize of a Tablet.
void:
void type represents undefined as the value. the undefined value represents "no value".
A variable can be declared with void type as below:
void type is commonly used to declare function return type. The function which does not return a value
can be declared with a void return type. If you don’t mention any return type for the function, the void
return type will be assigned by default.
Type Annotations
Type Annotation is a way to enforce type restriction to a specific variable or a function.
If a variable is declared with a specific data type and another type of value is assigned to the variable, a
compilation error will be thrown.
Enum:
Enum in TypeScript is used to give more friendly names to a set of numeric values.
For example, if you need to store a set of size variables such as Small, Medium, Large with different
numeric values, group those variables under a common enum called Size.
By default, enum’s first item will be assigned with zero as the value and the subsequent values will be
incremented by one.
In a shopping cart application, you can use a MobilePrice enum to store different prices of the mobile
depending on the mobile color.
Enum items can also be initialized with different values than the default value. If you set a different value
for one of the variables, the subsequent values will be incremented by 1.
Arrays
Consider the below page of the Mobile Cart application that displays the list of mobile phones available.
For each mobile in the list, you can see its image, name, price, and availability status.
This requirement is implemented using the concept of arrays of TypeScript. Let us discuss arrays in
TypeScript.
An Array is used to store multiple values in a single variable. You can easily access the values stored in
an array using the index position of the data stored in the array.
TypeScript array is an object to store multiple values in a variable with a type annotation. They are like
JavaScript arrays.
Arrays can be created using one of the below:
A TypeScript array defined with a specific type does not accept data of different types. TypeScript arrays
can be accessed and used much like JavaScript arrays.
JavaScript Arrays has several useful properties and methods to access or modify the given array. The
same is supported in TypeScript.
To add a dynamic value to an array, you can either use the push function or use the index reference.
Data can be removed from an array using the pop function or splice function
The splice function removes the item from a specific index position.
Tuple
Tuple type is a kind of array which accepts more than one predefined type of data. Arrays are used to
represent a collection of similar objects, whereas tuples are used to represent a collection of different
objects.
Let us consider an example, where customerCreditId, Customer object, and customerCreditLimit must be
represented in a data type.
The choice could be to define a class, with these properties. If it is represented using the class, then there
will be a requirement to instantiate the class and then the properties can be accessed.
Tuples provides an easy way to implement the same scenario with an array-like data structure, which is
easy to access and manipulate.
In the above example, the underlined error is due to multiple declarations in the first initialization which
violates the length restriction policy. To avoid this, the push method can be used as shown in the code.
Why Function?
Consider the below page that displays the list of mobile phones available. For each mobile in the list, you
can see its image, name, price, and availability status. The property ‘name’ of the mobile is clickable.
When the mobile name link is clicked, the user is navigated to the next screen which shows the details
specific to the phone selected. The details such as different colors in which the phone is available, price
of mobile according to the color selected, description of the phone, availability status, and discounts if
any.
Users can click on each color to view the mobile image for that color. The Price corresponding to the
color selected can also be shown. For example: On click of PinkGold the below screen should be
rendered:
This requirement is implemented using the function concept in TypeScript that helps us to implement
business logic and event handlers. Let us discuss functions in TypeScript.
Function in TypeScript Vs JavaScript:
A function is a block of statements to perform a particular task.
A sequence of statements written within function forms function body.
Functions are executed when it is invoked by a function call. Values can be passed to a function
as function parameters and the function returns a value.
Functions in TypeScript are like functions in JavaScript with some additional features.
TypeScript JavaScript
Types: Supports Do not support
Required and optional parameters: Supports All parameters are optional
Function overloading: Supports Do not support
Arrow functions: Supports Supported with ES2015
Default parameters: Supports Supported with ES2015
Rest parameters: Supports Supported with ES2015
With the TypeScript function, you can add types to the parameter passed to the function and the function
return types.
While defining the function, return the data with the same type as the function return type. While
invoking the function you need to pass the data with the same data type as the function parameter type, or
else it will throw a compilation error.
Arrow Function
Arrow function is a concise way of writing a function. Whenever you need a function to be written within
a loop, the arrow function will be the opt choice.
Do not use the function keyword to define an arrow function.
In a shopping cart application, you can use the arrow function to perform filtering, sorting, searching
operations, and so on.
In a class, if a method wants to access the property of the class it should use this keyword.
For a particular object, this keyword will help to access the properties of the current object. This is
possible because all the methods and properties are within the same scope.
In the above example, when you use this.productName inside the getProductDetails method,
getProductDetails method, and productName variable are in the same scope. Also, you get the desired
result.
But when you use this.productName inside the setTimeout function, instead of directly using it in
testThisFunction method, the scope of this.productName will be inside the
setTimeout's callback function and not the testThisFunction method. That is the reason you are unable
to access the value of productName for that particular object.
If you need to access the class scope with this keyword inside the callback function then use the
arrow function.
Arrow function lexically captures the meaning of this keyword.
Rewrite the same logic using the arrow function as below:
In the above code, this.productName is written inside an arrow function. Since the callback function of
setTimeout is implemented using the arrow function, it does not create a new scope and it will be in the
same scope as the testThisFunction method.
Function Types
Function types are a combination of parameter types and return type. Functions can be assigned to
variables.
While assigning a function to a variable make sure that the variable declaration is the same as the
assigned function’s return type.
In the above example, you have tried to invoke a function with only a single parameter, whereas the
definition of the function accepts two parameters. Hence, it will throw a compilation error. Also, optional
parameter can be used to tackle this issue.
The Optional parameter is used to make a parameter, optional in a function while invoking the function.
If you rewrite the previous code using an optional parameter, it looks like the below:
An Optional parameter must appear after all the mandatory parameters of a function.
Default parameter is used to assign the default value to a function parameter.
If the user does not provide a value for a function parameter or provide the value as undefined for it
while invoking the function, the default value assigned will be considered.
If the default parameter comes before a required parameter, you need to explicitly pass undefined as
the value to get the default value.
Rest Parameter
Rest Parameter is used to pass multiple values to a single parameter of a function. It accepts zero or more
values for a single parameter.
Rest Parameter should be declared as an array.
Precede the parameter to be made as rest parameter with triple dots.
Rest parameter should be the last parameter in the function parameter list.
Why Interface?
Interfaces can be used to impose consistency among various TypeScript classes.
Any class which implements an interface should implement all the required members of that
interface.
Interfaces can be used to ensure that proper values are being passed into functions, properties as
well as constructors.
Interfaces can be used to achieve additional flexibility as well as loosely coupling in
an application.
Any object which implements an interface can be passed as a parameter to a function whose
parameter type is declared the same as the interface.
Consider the below screen of the Mobile Cart application:
Here an array is used to store the product information. But not restricted the type of object to be stored
in the array. You can restrict the array which contains only a particular type of object. For this, use
Interface.
Let us discuss more on Interface in TypeScript.
What is an Interface?
An interface in TypeScript is used to define contracts within the code.
Interfaces are used to enforce type checking by defining contracts.
It is a collection of properties and method declarations.
Interfaces are not supported in JavaScript and will get removed from the generated JavaScript.
Interfaces are mainly used to identify issues upfront as we proceed with coding.
How to create an Interface?
Duck Typing
Duck-Typing is a rule for checking the type compatibility for more complex variable types.
TypeScript compiler uses the duck-typing method to compare one object with the other by comparing
that both the objects have the same properties with the same data types.
TypeScript interface uses the same duck typing method to enforce type restriction. If an object that has
been assigned as an interface contains more properties than the interface mentioned properties, it will be
accepted as an interface type and additional properties will be ignored for type checking
Let us rewrite the previous example to a pass additional parameter.
Defining an Interface
Interface keyword is used to declare an interface.
An interface should have properties and method declarations.
Properties or methods in an interface should not have any access modifiers.
Properties cannot be initialized in a TypeScript interface.
Function Types
Interfaces can be used to define the structure of functions like defining structure of objects.
Once the interface for a function type is declared, you can declare variables of that type and assign
functions to the variable if the function matches the signature defined in the interface.
Function type interface is used to enforce the same number and type of parameters to any function which
is been declared with the function type interface.
Extending Interfaces
An interface can be extended from an already existing one using the extends keyword.
In the code below, extend the productList interface from both the Category interface and Product
interface.
Class Types
Make use of the interface to define class types to explicitly enforce that a class meets a particular
contract. Use implements keyword to implement interface inside a class.
To enforce interface type on a class, while instantiating an object of a class declare it using the interface
type.
The only interface declared functions and properties will be available with the instantiated object.
Why Classes
Classes are used to create reusable components. Till the ES5 version of JavaScript, you do not have a
class concept as such. For implementing reusable components, use functions and prototype-based
inheritance. TypeScript provides an option for the developers to use object-oriented programming with
the help of classes.
In the Mobile Cart application, you can use a class to define the product and create various objects of
different products. In the below screen, creating different objects of product and rendering the details
Constructor
A constructor is a function that gets executed automatically whenever an instance of a class is created
using a new keyword.
To create a constructor, a function with the name as a "constructor" is used.
A class can hold a maximum of one constructor method per class.
You can use optional parameters with a constructor function as well.
Access Modifiers
Access modifiers are used to provide certain restriction of accessing the properties and methods outside
the class.
Instead of this declare the parameter itself with any of the access modifiers and reduce the lines of code
used for the initialization.
Let us rewrite the above code:
The subclass constructor function definition should invoke the superclass constructor using the super
function.
Use the super keyword to access the methods of the super class inside the subclass methods.
Override the superclass methods inside the subclass by specifying the same function signature.
Abstract Class
Abstract classes are base classes that may not be instantiated.
An abstract class can be created using abstract keyword.
Abstract methods within an abstract class are methods declared with abstract keyword and does
not contain implementation.
They must be implemented inside the derived classes.
Abstract classes can contain both abstract methods and its implementations.
Modules and Namespaces are useful in grouping functionalities under a common name.
The main use is reusability.
Code can be reused by importing modules or namespaces in other files.
Namespaces are used for namespace resolution and are suitable for the development of a smaller
application.
In larger-scale applications, they can be used to achieve modularity.
TypeScript provides native support in terms of module loaders using modules concept which takes care
of all the concerns with respect to modularity.
In the MobileCart application, create a product utility namespace or module and place the code related to
the product in it. Reuse the code related to the product by importing it into other files.
What is Namespace?
A Namespace is used to group functions, classes, or interfaces under a common name.
The content of namespaces is hidden by default unless they are exported.
Use nested namespaces if required.
The function or any construct which is not exported cannot be accessible outside the namespace.
In the below example, create a namespace called Utility and group a function MaxDiscountAllowed and
a nested namespace called payment inside it.
To import the namespace and use it, make use of the triple slash reference tag.
The file in which the namespace is declared and the file which uses the namespace to be compiled
together. It is preferable to group the output together in a single file. You have an option to do that by
using the --outFile keyword.
What is a Module?
Modules help us in grouping a set of functionalities under a common name. The content of modules
cannot be accessible outside unless exported.
Precede export keyword to the function, class, interface, etc.. which you need to export from a module.
Importing a Module
Using the import keyword, you can import a module within another module or another TypeScript
file. Provide the file name as the module name while importing.
Once the module is imported, make use of the classes and other constructs exported from the module.
Compiling Module
To compile the modules and the file which is using the module, compile them together using the tsc
command.
Commonly we compile the modular code in TypeScript to ES2015 format by using the --module ES2015
keyword while performing the compilation.
If none of the formats are mentioned in the compiler option, by default CommonJS module format will
be the one that gets generated while compiling modules in TypeScript.
A module loader interprets and loads a module written in a certain module format as well as helps in
importing all the dependent modules into developer working environment. At the runtime, they play a
very vital role in loading and configuring all needed dependencies modules before executing any linked
module.
The most commonly used module loaders in JavaScript are:
SystemJS module loader for modules in AMD, CommonJS, UMD, or System.register format
On-demand functionalities can be loaded by Modules, which is known as lazy loading. By using this
feature while executing our application all the declared modules are not loaded at that moment, it only
loads needed modules that are needed by the user to render the initial look of the application on the first
load. Due to this concept performance of the application can be enhanced as the initial startup time of the
application automatically decreases.
Default Exports
Default export is used to export any one of the constructs such as class, interface, function, and so on
from the current module as a default one.
Default exports are handy in case you need to export a class that has almost all functionalities
attached, such as javascript library object jQuery.
Name for the default exported constructs are optional. You can assign a name to the default construct
while importing it into the other file.
As you cannot have more than one default export per module.
Module Vs Namespace:
Module Namespace
Organizes code Organizes code
Have native support with Node.js module loader. All
No special loader required
modern browsers are supported with a module
loader.
ES2015 does not have a Namespace concept. It is
Supports ES2015 module syntax mainly used to prevent global namespace
pollution.
Suited for large-scale applications Suited for small-scale applications
Why Generics?
Generics helps us to avoid writing the same code again for different data types.
In TypeScript, generics are used along :
with function to invoke the same code with different type arguments
with Array to access the same array declaration with a different set of typed values
with Interface to implement the same interface declaration by different classes with different
types
with a class to access the same class with different types while instantiating it
What is Generics?
Generics is a concept using which we can make the same code work for multiple types.
It accepts type parameters for each invocation of a function or a class or an interface so that the same
code can be used for multiple types.
Consider the below code where you implement a similar function for two different types of data:
Avoid writing the same code again for different types using generics. Let us rewrite the above code using
generics:
To access this function with different types you will use the below code:
Generic Array:
Using Array<T>
Array<T> provides us the option to use the same array declaration for different types of data when used
along with a function.
<T> here represents the type parameter.
Generic Functions
Generic functions are functions declared with generic types.
Declaring generic function is done using the type parameter and using the same type variable for the
parameter and the return type.
Generic Interface
Generic interface is an interface that works with multiple types.
This interface can be implemented by different classes with their own types.
Generic Class
Generic class is a class that works with multiple types.
The same class instance can be instantiated and invoked with different type parameters.
Generic Constraints
Generic constraints are used to add constraints to the generic type.
Generic constraints are added using the 'extends' keyword.
To resolve this, you can add a constraint with the type parameter.
If you need to access a property on the type parameter, add those properties in an interface or class and
extend the type parameter from the declared interface or class.
Let us rewrite the previous code:
To invoke this generic function, you can pass any parameter which has a length property.