TypeScript - Classes & Interfaces

Classes

  • Class Definition
  • Class Fields
  • Class Methods
  • Using Constructor Methods
  • Access modifiers using private, public, protected, readonly
  • Using shorthand field initialization
  • Using this
/* Classes & Interfaces */

class Department {

  // Class Fields
  name: string;
  private employees: string[] = [];
  private readonly id: string;

  // Constructor method
  constructor(n: string) {
    this.name = n;
  }

  // Class Methods
  describe(this:Department){
      console.log("Describe - " + this.name);
  }

  addEmployee(employee: string) {
    this.employees.push(employee);
  }

  printEmployeeInfo(){
    console.log(this.employees.length);
    console.log(this.employees);
  }
}

const accounting = new Department("Accounting");

accounting.addEmployee("Max");
accounting.addEmployee("John");

// Problem (Accessing Class Fields)
// accounting.employees[3] = "Todd";

accounting.printEmployeeInfo();
accounting.describe();
console.log(accounting);

// const accountCopy = { name: 'Mathematics', describe: accounting.describe }
// accountCopy.describe();

Using Shorthand Initialization

constructor(private id: string, public name: string) {

}

Getter / Setters

  private lastReportDateTime!: string;

  /* Getter */
  get getLastReportDateTime(){
    return this.lastReportDateTime;
  }

  /* Setter */
  set setLastReportDateTime(value: string){
    if (!value) {
      throw new Error("Empty Input");
    }
    
    this.lastReportDateTime = value;
  }

Static Methods and Properties

  • Often Used for Utility Functions
  • You donot need to instantiate class to use the methods
  • Static methods and properties are not accessible directly on instance methods. They are dettached from the instance

Inheritance

  • Extending Classes using extends keyword
class ITDepartment extends Department{
  constructor(name: string, public admins: string[]){
    super(name);
  }

  printITReport(this: ITDepartment){
    console.log("Printing IT Report for " + this.name)
  }
}

Abstract Classes

  • Enforce inherit class to implement their own methods, we use Abstract Classes
  • Abstract classes cannot be instantiated. Only the inherited classes can be instantiated
abstract class Department {
  protected name: string;

  constructor(n: string) {
    this.name = n;
  }

  // Class Methods
  abstract describe(this:Department): void
}

class Accounting extends Department{
  describe(this: Accounting): void {
    console.log("Describe - " + this.name);
  }
  
}

Singleton Pattern

  • Singleton pattern using private constructor
class Pizza {
  items: string[] = [];
  private static instance: Pizza;

  private constructor(...item: string[]){
    this.items.push(...item);
  }

  static getInstance(): Pizza{
    if (Pizza.instance) {
      return Pizza.instance;
    }

    Pizza.instance = new Pizza("Cheese");
    return Pizza.instance;    
  }
}

let cheesePizza = Pizza.getInstance();
console.log(cheesePizza);

Interfaces

  • Interface is pure Typescript feature. It is not available in Javascript. It is provided during the development and compile time only.
  • Interface can be used to Typecheck variable / objects.
  • Interface provides clear way to define structure of an object.
  • Interface can also be used to define structure of function (Replacement of Function Types)
  • Class can implement Interfaces (Class can implement multiple interfaces)
  • Interface provides contract for an object
  • You can inhert from multiple interfaces
interface Greeter {
  name: string;
  readonly id: string;
  outputName?: string;    // Marking as Optional Field

  greet(phrase: string): void;
}
let user1: Greeter;
user1 = {
  id: (Math.random() * 16).toString(),
  name: 'Max',
  greet(phrase) {
      console.log(phrase + " there!! I am " + this.name);
  },
}

console.log(user1);
user1.greet("Ola");
class Person implements Greeter {
  name: string;
  id: string;
  email!: string;           // Marking as Optional Field

  constructor(name: string){
    this.name = name;
    this.id = (Math.random() * 16).toString();
  }
  
  greet(this: Person, phrase: string = 'Hello'): void {
    console.log(phrase + " there!! I am " + this.name);
  }
}

const waiter = new Person("Waiter");
waiter.greet("Namaste");
interface AddFn {
  (a: number, b: number): number;
}