TypeScript - Going Beyond The Basics | HostKicker

TypeScript – Going Beyond The Basics

If you are a programmer efficient in JavaScript and have begun studying the basics of Typescript as well, this article will help you understand some of the advanced workings of TypeScript. 

Abstract Classes

TypeScript has 2 types of classes whereas JavaScript only had one. One is the regular class whose functionalities are the same as the classes in JavaScript. An abstract class is the second type and it helps in defining the base class. The base class can be used for defining sets of core properties and functions that you want the child classes to be inheriting. A base can be created with the help of an ordinary class too, but when the base class is made abstract, you will be able to specify specific properties and functions that will have to be defined by the child class. An abstract class cannot be used to create an instance, meaning you cannot use an abstract class for creating an instance. 

Adding some more properties to the above class:

The PI mentioned first is a regular property, it is declared as such because its value is not intended to change. calcType, the second property is abstract. If a property is made abstract, the child class will have to define it. Creating a child class SimpleCalculator for Calculator: 

An error is indicated which can be fixed by using the quick fix option and choosing Implement Inherited Abstract Class. 

Providing a value to calcType:

Here calcType property is abstract and hence will be defined in the child class. The keyword abstract is not used while defining calcType in the child class. Creating 2 more child classes under Calculator:

The child class is forced to give a definition of its own to the calcType. This makes sure that there is a proper configuration of the child class. The child class can have varying behaviour that is independent of the base class.  The base class does not need modifications for every child class that is defined during the lifetime of the application. 

SOLID and the Open-Closed Principle

Object-oriented programming is ruling the world right now, and here you will soon be faced with designing principles termed SOLID. The principle has 5 parts, and the O is for an open-closed principle. This means that a class is open for it to be extended but when it comes to any modifications, it is closed. This is helpful in a scenario where if an application has numerous dependent classes and later a base class is modified, it would essentially break all the other classes that depended on it. 

The Protected Modifier and an Abstract Method

When you create a child class from an existing class, the process is termed as an inheritance. TypeScript has features like a visibility modifier which allows the programmer to change and control what properties of the child class created will be inherited and which of the properties will only be accessible in the parent or base class. 

If a method or property is declared as private, it will not be inherited. The property or method that is marked as protected will be inherited. The properties or methods that are declared as public will be inherited. In general, methods are kept as public and properties are kept as protected. Adding 2 additional methods in the class Calculator, one abstract and one regular. 

After this, you want to work on fixing the errors, which can be done through the “implement inherited abstract class for each child class option”. Each child class will inherit a method sum, whose definition is in the Calculator base class. All child classes will also have to provide their own implementation to the method mul. Deleting the class GraphingCalculator and providing different implementations of mul: 

The SimpleCalculator class as a device is primitive and multiplication is performed through repetitive addition. On the other hand, ScientificCalculator has circuitry built into it for the purpose of carrying out multiplications. Both these subclasses have the pre-defined method sum from the class Calculator. 

Calculators and Constraining Generics

Observing the 2 snippets of code:

The instance of the child class is kept the same as that of the type of the base class, meaning the child class instances can be treated as if they are of the same type. 

Calculator shopping cart

If you are working on an online store, whose purpose is selling calculators, each customer that visits the store site should have their own shopping cart for the purpose of ordering. The shopping cart will be storing the orders made in the form of an array:

The class can be modified so it accepts general parameters of type T, T can be the representation of any type. 

Constraining the generic parameter:

The code here “T extends SimpleCalculator | ScientificCalculator” makes use of a union in order to constrain T to be one of two types. But if there are calculators of more than 2 types listing out each possibility will be too difficult. The base class definition will have to undergo constant modifications, something that goes against the principle of the open class. But since the Calculator child classes are deriving their methods and properties from the same base class instance, and have the same type as the base, the constraint can be shortened:

Design Patterns and the Singleton Pattern

An important concept in all object-oriented programming languages is designing patterns. A design pattern is a series of solutions that present themselves to common programming problems. A few dozen of them exist and it is imperative to have an understanding of them as they can be commonly asked during the construction of an API or a framework. The O in SOLID is obeyed in design patterns as well. 

A singleton pattern gives the programmer the ability to restrict the class so that it has one instance from it. A special method is also made available for providing cards to this one instance. A good candidate for a singleton is the shopping cart. One instance of a shopping cart is wanted in the front-end of the online store application. No matter where the user is in the application, it is important to ensure that they have access to and modify the same shopping cart. Changing the ShoppingCart into a singleton takes 3 steps. 

Creating a self-referencing property

This class is used to store the reference to the only shopping cart. The reference property is static so it is residing in the class instead of in the instance. A property that is static will not be able to take a variable of the generic type. Specifying one is required, here it is Calculator. This allows the reference to be null which can be important. 

Providing a static access point

The access point here is a static method. This means that it cannot take or return a variable or generic type. The way to create an instance of the shopping cart is shown through getCart. It is checking if the shopping cart has already been created. First, the reference to cart is null, then the getCart is invoking the constructor, setting the static property of the cart to the new instance created. The if statement is blocking any snippet of the code from creating another instance of the shopping cart. Each call after this made to the getCart will return to the same instance of the cart. 

Blocking off the constructor

The last step involves preventing any code snippet from making use of the new operator with the class ShoppingCart. This can be achieved by declaring the constructor as private:

This makes the constructor such that it is only available in this class. The new keyword will be of any use outside the class for creating a new instance of ShoppingCart

The static method getCart is used for accessing the shopping cart. 

This means the application will only contain one copy of the shopping cart for every user, regardless of where in the application or code it is. The shopping cart will also only be accepting items that are calculators. 

A quick aside on visibility modifiers

The visibility modifiers public, private and protected help in controlling how the inheritance works between the parent or the base class and the class. It is also useful in specifying if a particular property or method can be accessible from outside the class or not. Property or method that is made public will be open to the outside world, the ones that are kept either protected or private will be blocked. A change in the visibility specifier of the constructor will either put restrictions on access to the constructor or not. The new keyword will no longer be effective in creating an instance of ShoppingCart from outside. 

Function Overloading

Object-oriented programming languages like Java and C++ give the programmer the option to write many methods that have the same name but different parameters:

This code is in Java because it is easier to understand function overloading concepts in Java. Here are 4 versions of the method names as greet, and they are different from the others in terms of the number of properties and their types, also called their signatures. The execution of this code begins with the main function, whose purpose is to call greet 4 times. In Java, a match will be searched with the number of arguments and their types in order to determine which version of the greet method should be used. 

The code can also be reused from one version of the method inside another by programming them as a chain. The greet method will take 2 strings in order to call the version that takes one string, which will call the version of the method that has no arguments, which prints the statement “Hello”. The methods that have been overloaded do not have to have the code that prints the statement. 

TypeScript does not have this straightforward way of function overloading. 

This code has a similar function to that of the code discussed above in Java, but the formatting is not as neat. But it is important to understand it. The Jody of only one version of the function is defined. It is in the general form when looking at how parameters are accepted. In line 155, param1 serves the purpose of a required parameter, this means that all the overloaded versions created will have to have at least one argument. The type of the argument for param1 for the overloaded functions should be one of the types that have been specified in a general form. 

param2 is the second argument, and it has been marked optional. This means overloads can be created with either one or two arguments. An overload with a second argument should only be of string type. There is no version with zero arguments, but an equivalent can be created by setting the type of param1 as undefined in one of the versions.

Leave a Comment