TypeScript Classes Explained

TypeScript Classes Explained

15 Oct 2024
Advanced
6.92K Views
20 min read
Learn with an interactive course and practical hands-on labs

TypeScript Programming Course

TypeScript Classes

Typescript classes are one of TypeScript's most powerful features is its class system. Classes in TypeScript enable you to define blueprints for things, making your code more organized, reusable, and understandable.Imagine you're developing a massive application. TypeScript classes allow you to neatly bundle data and functionality.

So In this TypeScript Tutorial, We are going to explore Typescript classes including constructors, access modifiers etc.

Defining Classes in TypeScript

TypeScript classes build upon JavaScript's class syntax, introducing type annotations and additional features that promote robust and maintainable code.

Class Members

Class members in TypeScript can include properties, methods, and constructors. Each member can have a type annotation to enforce type safety.

class Person {
  name: string;
  age: number;

  greet(): void {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

Constructors

Constructors are special methods used to initialize class instances. TypeScript allows specifying parameter types and can ownaccess modifiers directly in constructor parameters to define and initialize class members succinctly.

class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

Shorthand Syntax with Access Modifiers:

TypeScript allows declaring and initializing class members directly within the constructor parameters using access modifiers (public, private, protected, readonly).

class Person {
  constructor(public name: string, private age: number) {}
}

Access Modifiers

Access modifiers control the visibility of class members, promoting encapsulation and data hiding.

  • Public (public): Default modifier. Members are accessible from anywhere.
  • Private (private): Members are accessible only within the class.
  • Protected (protected): Members are accessible within the class and its subclasses.
  • Readonly (readonly): Members cannot be reassigned after initialization.
class Person {
  public name: string;
  private age: number;
  protected address: string;
  readonly id: number;

  constructor(name: string, age: number, address: string, id: number) {
    this.name = name;
    this.age = age;
    this.address = address;
    this.id = id;
  }
}

Inheritance

TypeScript supports class inheritance, allowing one class to extend another, inheriting its properties and methods. The superkeyword is used to call the parent class's constructor and methods.

class Employee extends Person {
  employeeId: number;

  constructor(name: string, age: number, address: string, id: number, employeeId: number) {
    super(name, age, address, id);
    this.employeeId = employeeId;
  }

  displayEmployeeId(): void {
    console.log(`Employee ID: ${this.employeeId}`);
  }
}

Getters and Setters

Getters and setters provide controlled access to class properties, enabling validation and encapsulation.

class Person {
  private _age: number;

  constructor(age: number) {
    this._age = age;
  }

  get age(): number {
    return this._age;
  }

  set age(value: number) {
    if (value < 0) {
      throw new Error("Age cannot be negative.");
    }
    this._age = value;
  }
}

Static Members

Static members belong to the class itself rather than to instances. They are accessed using the class name.

class MathUtils {
  static PI: number = 3.14159;

  static calculateCircumference(radius: number): number {
    return 2 * MathUtils.PI * radius;
  }
}

console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.calculateCircumference(5)); // 31.4159

Abstract Classes

Abstract classes cannot be instantiated directly and are meant to be subclassed. They can contain abstract methods that must be implemented by subclasses.

abstract class Animal {
  abstract makeSound(): void;

  move(): void {
    console.log("Moving...");
  }
}

class Dog extends Animal {
  makeSound(): void {
    console.log("Bark!");
  }
}

const dog = new Dog();
dog.makeSound(); // Bark!
dog.move();      // Moving...

Implementing Interfaces

Classes can implement interfaces to ensure they adhere to specific contracts, promoting consistency and type safety.

interface IEmployee {
  employeeId: number;
  getSalary(): number;
}

class Employee implements IEmployee {
  constructor(public employeeId: number, private salary: number) {}

  getSalary(): number {
    return this.salary;
  }
}

Generics in Classes

Generics enable classes to operate with various types while maintaining type safety.

class Box<T> {
  contents: T;

  constructor(value: T) {
    this.contents = value;
  }

  getContents(): T {
    return this.contents;
  }
}

const numberBox = new Box<number>(123);
console.log(numberBox.getContents()); // 123

const stringBox = new Box<string>("Hello");
console.log(stringBox.getContents()); // Hello

Examples

Example 1: Basic Class

class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): void {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

const person = new Person("John", 30);
person.greet(); // Hello, my name is John.

Example 2: Inheritance and Access Modifiers

class Animal {
  protected name: string;

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

  move(): void {
    console.log(`${this.name} is moving.`);
  }
}

class Dog extends Animal {
  constructor(name: string) {
    super(name);
  }

  bark(): void {
    console.log(`${this.name} is barking.`);
  }
}

const dog = new Dog("Buddy");
dog.move(); // Buddy is moving.
dog.bark(); // Buddy is barking.

Example 3: Implementing Interfaces

interface Vehicle {
  speed: number;
  accelerate(): void;
}

class Car implements Vehicle {
  speed: number = 0;

  accelerate(): void {
    this.speed += 10;
    console.log(`Speed: ${this.speed}`);
  }
}

const car = new Car();
car.accelerate(); // Speed: 10

Example 4: Abstract Classes and Generics

abstract class Shape {
  abstract calculateArea(): number;

  describe(): void {
    console.log("This is a shape.");
  }
}

class Circle extends Shape {
  constructor(public radius: number) {
    super();
  }

  calculateArea(): number {
    return Math.PI * this.radius ** 2;
  }
}

const circle = new Circle(5);
console.log(circle.calculateArea()); // 78.53981633974483

Differences Between JavaScript and TypeScript Classes

While TypeScript classes are similar to JavaScript ES6 classes, they introduce several key differences:

  • Type annotations, enforcing static types.
  • Access modifiers (public, private, protected), enhancing encapsulation.
  • Generics support in classes and methods.
  • Abstract classes for better inheritance modeling.

In detailed

FeatureJavaScript ClassesTypeScript Classes
Type AnnotationsNot available. JavaScript does not support type annotations.Supports type annotations for properties, parameters, and return values, enhancing type safety.
Access ModifiersJavaScript classes do not have access to modifiers.Provides public, private, and protected access modifiers to control visibility of class members.
Read-only PropertiesNo built-in support for read-only properties.Supports the readonly modifier to create immutable properties.
Interface ImplementationJavaScript classes cannot implement interfaces.TypeScript classes can implement interfaces, ensuring they conform to specific contracts.
GenericsJavaScript does not support generics.TypeScript supports generics, allowing classes to be more flexible while maintaining type safety.
Compile-time Type CheckingNo type checking at compile-time. Errors are caught at runtime.TypeScript performs type checking at compile-time, preventing many runtime errors.
Constructor ShorthandNo shorthand for defining and initializing properties in the constructor.Supports parameter properties, where properties are automatically declared and initialized from constructor parameters.
Abstract ClassesNo support for abstract classes.Supports abstract classes and methods, enforcing subclasses to implement specific behaviors.
DecoratorsDecorators are not natively supported. Experimental via external libraries.TypeScript provides experimental support for decorators using the experimentalDecorators option.
Static TypingJavaScript is dynamically typed.TypeScript is statically typed, requiring explicit type declarations or type inference.
Default Access ModifierClass members are public by default.Same as JavaScript; class members are public unless specified otherwise.
Strict Null ChecksNo strict null checks. Null or undefined can be assigned to variables freely.TypeScript has strict null checks, preventing null or undefined from being assigned to variables without proper handling.

    Advanced Features

    1. Decorators

    Decorators in TypeScript are a special kind of declaration that can be applied to classes, methods, properties, or parameters to modify their behavior.

    2. Mixins

    Mixins allow the composition of reusable functionalities across multiple classes, bypassing traditional inheritance.

    Best Practices

    • Use access modifiers to control the visibility and access of class members.
    • Have abstract classes and interfaces to define reusable and consistent code structures.
    • Employ generics for flexibility while maintaining type safety.
    • Write concise and self-documenting code by using getters and setters.
    • Avoid deeply nested inheritance hierarchies to prevent tight coupling and maintain simplicity.
    Conclusion

    TypeScript classes extend the capabilities of JavaScript by introducing static typing, access modifiers, and advanced OOPs features such as abstract classes and generics. Mastering TypeScript classes allows developers to write more predictable, scalable, and maintainable code. By adhering to best practices, TypeScript developers can harness the full power of object-oriented programming.

    FAQs

    TypeScript classes have some added benefits though like the ability to declare public and private variables, the ability to use generics, etc. A “type” in Typescript, on the other hand, can be a number, string, boolean, array, etc.

    The typeof operator is a standard JavaScript operator recognized by TypeScript for checking the type of variables and objects

    Classes provide the features of Object-oriented programming So it makes our code more usable, maintainable, and scalable so is such a case we should use classes in TypeScript. Their functionality of classes is useful in handling the large code base with efficiency.

    Take our Typescript skill challenge to evaluate yourself!

    In less than 5 minutes, with our skill challenge, you can identify your knowledge gaps and strengths in a given skill.

    GET FREE CHALLENGE

    Share Article
    About Author
    Shailendra Chauhan (Microsoft MVP, Founder & CEO at Scholarhat by DotNetTricks)

    Shailendra Chauhan is the Founder and CEO at ScholarHat by DotNetTricks which is a brand when it comes to e-Learning. He provides training and consultation over an array of technologies like Cloud, .NET, Angular, React, Node, Microservices, Containers and Mobile Apps development. He has been awarded Microsoft MVP 9th time in a row (2016-2024). He has changed many lives with his writings and unique training programs. He has a number of most sought-after books to his name which has helped job aspirants in cracking tough interviews with ease.
    Accept cookies & close this