Typescript Classes | Typescript Tutorials

typescript Aug 10, 2019

Typescript Classes

What is Typescript Classes ? Most of the preceding information on the TypeScript language has concerned various methods of annotating your code with type information. although it is important to understand all the various type annotations, TypeScript has powerful type inference that can do a lot of the work for you. The structural elements, on the other hand, will become familiar tools molded to the shape of
your hands. Classes are the most fundamental structural element when it comes to organizing you program.


There are quite a few aspects to learn when working with classes, but if you have any previous experience with class-based object orientation, many of the features will be recognizable, even if the details
or syntax are new.

Constructors

All classes in TypeScript have a constructor, whether you specify one or not. If you leave out the constructor, the compiler will automatically add one. For a class that doesn’t inherit from another class, the automatic constructor will be parameterless and will initialize any class properties. Where the class extends another class, the automatic constructor will match the superclass signature and will pass arguments to the superclass before initializing any of its own properties. below code  shows two classes that have a manually written constructor. It is a slightly longer example , but it is worth reading through it before each aspect is explained.

class Song {
    constructor(private artist: string, private title: string) {
    }
    play() {
    console.log('Playing ' + this.title + ' by ' + this.artist);
    }
}
class Jukebox {
	constructor(private songs: Song[]) {
}
play() {
    const song = this.getRandomSong();
    song.play();
}

private getRandomSong() {
    const songCount = this.songs.length;
    const songIndex = Math.floor(Math.random() * songCount);
    return this.songs[songIndex];
}
}
const songs = [
    new Song('Bushbaby', 'Megaphone'),
    new Song('Delays', 'One More Lie In'),
    new Song('Goober Gun', 'Stereo'),
    new Song('Sohnee', 'Shatter'),
    new Song('Get Amped', 'Celebrity')
];
const jukebox = new Jukebox(songs);
jukebox.play();

One of the first things that may strike you about the example is that the constructor parameters are not mapped to member variables. If you prefix a constructor parameter with an access modifier, such as private, it will automatically be mapped for you. You can refer to these constructor parameters as if they were declared as properties on the class; for example, this.title, can be used anywhere within the Song
class to obtain the song title on that instance. code below  shows equivalent code where the parameters are manually mapped, but this is to illustrate the point that this creates a lot of redundant code, and you should avoid this approach.

class Song {
    private artist: string;
    private title: string;
    constructor(artist: string, title: string) {
        // Don't do this!
        this.artist = artist;
        this.title = title;
    }
    play() {
    	console.log('Playing ' + this.title + ' by ' + this.artist);
    }
}

Access Modifiers

Access modifiers change the visibility of class members. There are three access modifiers available in
TypeScript:
• private
• protected
• public

The private modifier restricts the visibility to the same-class only. When you use the private modifier on a member, it won’t appear in autocompletion (which is a strong hint that you can’t use it) and attempts to access the member from outside the class will result in a compiler error. You cannot even access the member
from a subclass.

The protected modifier allows the member to be used within the same-class, and within subclasses. Access from anywhere else is not allowed. The public modifier, which is the default for class members, allows access from all locations. It is not
necessary to specify the public keyword on a property or method unless you want to be explicit – but you will need to add it to constructor parameters to have them mapped to properties automatically.
                                                               When considering the visibility of class members, it is worth starting with the least visible access modifier, which is private. When a member is private, you can make changes to it knowing it is only used within the class you are changing. As you increase the visibility of members, you also increase the complexity of changes, and your blood pressure when you attempt to refactor your code. Access modifiers are a key component of encapsulation. When you are about to change a private member to become public, consider whether the code actually ought to be moved into the class instead. Access modifiers are removed during compilation, so access is not controlled at runtime, but enforced logically during the compilation.

Properties and Methods

Instance properties are typically declared before the constructor in a TypeScript class. A property definition consists of three parts: an optional access modifier, the identifier, and a type annotation. For example: public name: string;. You can also initialize the property with a value: public name = 'Jane'; When
your program is compiled, the property initializers are moved into the top of the constructor, so they run before any code you place in the constructor.

Instance properties can be accessed from within the class using the this keyword. If the property is public it can be accessed using the instance name.You can also add static properties to your class, which are defined in the same way as instance
properties, but with the static keyword between the access modifier (if one is specified) and the identifier.Static properties are accessed using the class name as shown in below code , where the static maxSongCount property is accessed using Playlist.maxSongCount — even within a method on the class; this is because the
property is not defined on each instance.

You can make both static and instance properties read-only to prevent the values being overwritten. The maxSongCount static property has been marked as readonly to prevent the value from being changed
from 30.

class Playlist {
    private songs: Song[] = [];
    static readonly maxSongCount = 30;
    constructor(public name: string) {
    }
    addSong(song: Song) {
        if (this.songs.length >= Playlist.maxSongCount) {
        throw new Error('Playlist is full');
    }
    this.songs.push(song);
    }
}
// Creating a new instance
const playlist = new Playlist('My Playlist');
// Accessing a public instance property
const name = playlist.name;
// Calling a public instance method
playlist.addSong(new Song('Therapy?', 'Crooked Timber'));
// Accessing a public static property
const maxSongs = Playlist.maxSongCount;
// Error: Cannot assign to a readonly property
Playlist.maxSongCount = 20;

Methods are defined a lot like functions, but
they leave out the function keyword. You can annotate a method with all the parameters and return value type annotations that were discussed earlier in the section on functions. You can prefix the method name with an access modifier to control its visibility, which is public by default. Just as with instance properties,
methods can be accessed from within the class using the this keyword; and if they are public they can be accessed outside of the class using the instance name.

You can create static methods by prefixing the method name with the static keyword. Static members can be called even when no instance of the class has been created and only a single instance of each static member exists in your program. All static members are accessed via the class name and not an instance name and static members have no access to nonstatic properties or methods.

TypeScript supports property getters and setters, if you are targeting ECMAScript 5 or above. The syntax for these is identical to method signatures as described in the following, except they are prefixed by either the get or set keyword. As shown in code below, property getters and setters allow you to wrap property access with a method while preserving the appearance of a simple property to the calling code.

interface StockItem {
description: string;
asin: string;
}
class WarehouseLocation {
    private _stockItem: StockItem;
   	 constructor(public aisle: number, public slot: string) {
    }
    get stockItem() {
   	 return this._stockItem;
    }
    set stockItem(item: StockItem) {
   	 this._stockItem = item;
    }
}
const figure = { asin: 'B001TEQ2PI', description: 'Figure' };
const warehouseSlot = new WarehouseLocation(15, 'A6');
warehouseSlot.stockItem = figure;

Abstract Classes

An abstract class can be used as a base class, but can’t be instantiated directly. Abstract classes can contain implemented methods as well as abstract methods, which have no implementation and must be implemented by any subclass.

an abstract logger class with an abstract notify method, and an implemented
protected getMessage method. Each subclass must implement the notify method, but can share the getMessage implementation from the base class.

abstract class Logger {
    abstract notify(message: string): void;
    protected getMessage(message: string): string {
   			 return `Information: ${new Date().toUTCString()} ${message}`;
    }
}
class ConsoleLogger extends Logger {
    notify(message) {
   		 console.log(this.getMessage(message));
    }
    }
    class InvasiveLogger extends Logger {
        notify(message) {
        alert(this.getMessage(message));
    }
}
let logger: Logger;
// Error. Cannot create an instance of an abstract class
logger = new Logger();
// Create an instance of a sub-class
logger = new InvasiveLogger();
logger.notify('Hello World');

Abstract classes are like interfaces, in that they contain a contract that may have no implementation.They can add to this with implementation code, and can specify access modifiers against the members: two things that interfaces cannot do

Neeraj Dana

Experienced Software Engineer with a demonstrated history of working in the information technology and services industry. Skilled in Angular, React, React-Native, Vue js, Machine Learning