TypeScript Classes: Syntax, Inheritance, Access Modifiers, Constructors & Abstract Classes

1. What are classes and objects in TypeScript?

Class: A blueprint for creating objects, defining properties and methods with type annotations.

Object: An instance of a class, created using the new keyword.

Use Case: Modeling entities (e.g., users, products) with structured data and behavior.

Can you give an example of classes and objects?


class Employee {
  name: string;
  salary: number;
  constructor(name: string, salary: number) {
    this.name = name;
    this.salary = salary;
  }
  displayInfo(): string {
    return `Name: ${this.name}, Salary: $${this.salary}`;
  }
}
// Creating objects
const emp1: Employee = new Employee("kristal", 60000);
const emp2: Employee = new Employee("Sashi", 55000);
console.log(emp1.displayInfo());
console.log(emp2.displayInfo());
    

Output:


Name: kristal, Salary: $60000
Name: Sashi, Salary: $55000
    

2. What is the class syntax and what are class members in TypeScript?

Class Syntax:


class ClassName {
  // Properties
  propertyName: type;
  // Constructor
  constructor(params: type) { ... }
  // Methods
  methodName(): returnType { ... }
}
    

Members:

Use Case: Encapsulating data and behavior; static members for shared utilities.

Can you give an example of class syntax and members?


class Company {
  static companyName: string = "TechCorp"; // Static property
  employeeCount: number; // Instance property
  constructor(employeeCount: number) {
    this.employeeCount = employeeCount;
  }
  // Instance method
  getSummary(): string {
    return `${Company.companyName} has ${this.employeeCount} employees`;
  }
  // Static method
  static getCompanyName(): string {
    return Company.companyName;
  }
}
// Usage
const company: Company = new Company(100);
console.log(company.getSummary());
console.log(Company.getCompanyName());
    

Output:


TechCorp has 100 employees
TechCorp
    

3. What are access modifiers in TypeScript?

Access Modifiers: Control visibility of class members.

Use Case: Enforcing encapsulation and controlling access to sensitive data.

Can you give an example of access modifiers?


class Employee {
  public name: string;
  private salary: number;
  protected department: string;
  constructor(name: string, salary: number, department: string) {
    this.name = name;
    this.salary = salary;
    this.department = department;
  }
  private getSalary(): number { return this.salary; }
  public getDetails(): string {
    return `${this.name} in ${this.department}, Salary: $${this.getSalary()}`;
  }
}
class Manager extends Employee {
  constructor(name: string, salary: number, department: string) {
    super(name, salary, department);
  }
  public getDepartment(): string {
    return this.department; // Protected member accessible
  }
}
// Usage
const emp: Employee = new Employee("kristal", 60000, "IT");
console.log(emp.getDetails());
// console.log(emp.salary); // Error: 'salary' is private
const mgr: Manager = new Manager("Sashi", 80000, "HR");
console.log(mgr.getDepartment());
    

Output:


kristal in IT, Salary: $60000
HR
    

4. What are constructors and parameter properties in TypeScript?

Constructor: A special method called when creating an object, defined with constructor.

Parameter Properties: Shorthand to declare and initialize class properties directly in the constructor.

Use Case: Simplifying class definitions by reducing boilerplate.

Can you give an example of constructors and parameter properties?


class Product {
  constructor(
    public name: string,
    private price: number
  ) {} // Parameter properties
  public getInfo(): string {
    return `${this.name}: $${this.price}`;
  }
}
// Usage
const prod: Product = new Product("Laptop", 1000);
console.log(prod.getInfo());
// console.log(prod.price); // Error: 'price' is private
prod.name = "Tablet";
console.log(prod.getInfo());
    

Output:


Laptop: $1000
Tablet: $1000
    

5. What are inheritance and method overriding in TypeScript?

Inheritance: A class (child) inherits properties and methods from another class (parent) using extends.

Method Overriding: Child class provides a specific implementation of a parent class method.

Use Case: Reusing and specializing behavior (e.g., specific employee types).

Can you give an example of inheritance and method overriding?


class Person {
  constructor(public name: string) {}
  describe(): string { return `Person: ${this.name}`; }
}
class Employee extends Person {
  constructor(name: string, private salary: number) {
    super(name);
  }
  describe(): string { // Method overriding
    return `Employee: ${this.name}, Salary: $${this.salary}`;
  }
}
// Usage
const person: Person = new Person("hari");
const emp: Employee = new Employee("kristal", 60000);
console.log(person.describe());
console.log(emp.describe());
    

Output:


Person: hari
Employee: kristal, Salary: $60000
    

6. What are abstract classes and methods in TypeScript?

Abstract Class: A class that cannot be instantiated directly, used as a base for other classes.

Abstract Method: A method declared without implementation, requiring subclasses to provide it.

Use Case: Defining a common interface with partial implementation for subclasses.

Can you give an example of abstract classes and methods?


abstract class Vehicle {
  constructor(public brand: string) {}
  abstract drive(): string; // Abstract method
  getInfo(): string { // Concrete method
    return `Brand: ${this.brand}`;
  }
}
class Car extends Vehicle {
  drive(): string { return `${this.brand} car is driving`; }
}
class Truck extends Vehicle {
  drive(): string { return `${this.brand} truck is hauling`; }
}
// Usage
const car: Vehicle = new Car("Toyota");
const truck: Vehicle = new Truck("Ford");
console.log(car.getInfo());
console.log(car.drive());
console.log(truck.getInfo());
console.log(truck.drive());
// const vehicle = new Vehicle("Generic"); // Error: Cannot instantiate abstract class
    

Output:


Brand: Toyota
Toyota car is driving
Brand: Ford
Ford truck is hauling
    

7. Can you provide a comprehensive example of TypeScript classes?

Project Structure:


ts-classes/
├── src/
│   └── main.ts
├── tsconfig.json
└── package.json
    

main.ts:


// Comprehensive example
class Department {
  static companyName: string = "TechCorp"; // Static property
  protected employees: string[] = []; // Protected property
  constructor(public name: string) {}
  addEmployee(employee: string): void { this.employees.push(employee); }
  protected getEmployeeCount(): number { return this.employees.length; }
  static getCompanyInfo(): string { return `Company: ${Department.companyName}`; }
}
abstract class Employee extends Department {
  abstract getRole(): string; // Abstract method
  constructor(
    public name: string,
    private salary: number,
    department: string
  ) { super(department); }
  getDetails(): string {
    return `${this.name} in ${this.name}, Salary: $${this.salary}, Employees in dept: ${this.getEmployeeCount()}`;
  }
}
class Developer extends Employee {
  constructor(name: string, salary: number, department: string) {
    super(name, salary, department);
  }
  getRole(): string { return `Developer in ${this.name}`; }
  addEmployee(employee: string): void { // Override
    super.addEmployee(employee);
    console.log(`Added ${employee} to ${this.name}`);
  }
}
// Usage
try {
  const dev: Employee = new Developer("kristal", 60000, "IT");
  dev.addEmployee("Sashi");
  console.log(dev.getDetails());
  console.log(dev.getRole());
  console.log(Department.getCompanyInfo());
} catch (error) {
  console.error(`Error: ${error}`);
}
    

package.json:


{
  "name": "ts-classes",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && node dist/main.js",
    "build": "tsc",
    "watch": "tsc --watch"
  },
  "devDependencies": {
    "typescript": "^5.6.2"
  }
}
    

tsconfig.json:


{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
    

Steps to Run:

  1. Create the project structure.
  2. Install dependencies: npm install.
  3. Compile: npm run build.
  4. Run: npm start.

Output:


Added Sashi to IT
kristal in IT, Salary: $60000, Employees in dept: 1
Developer in IT
Company: TechCorp
    

Description:

8. What are common mistakes in TypeScript classes?

9. What are best practices for TypeScript classes?

  1. Class Syntax/Members:
    • Use explicit type annotations for all properties and methods.
    • Define static members for shared data or utilities.
  2. Access Modifiers:
    • Use private for internal data; protected for subclass access.
    • Expose only necessary members as public.
  3. Constructors/Parameter Properties:
    • Use parameter properties to reduce boilerplate.
    • Initialize all properties in the constructor.
  4. Inheritance/Overriding:
    • Call super() in subclass constructors and overridden methods.
    • Ensure overridden methods match parent signatures.
  5. Abstract Classes/Methods:
    • Use abstract classes for shared logic with required subclass implementations.
    • Clearly document abstract methods' expected behavior.
  6. General:
    • Follow TypeScript naming conventions: CamelCase for classes, camelCase for members.
    • Use tsc with strict mode (strict: true in tsconfig.json).
    • Test with edge cases (e.g., invalid inputs, subclass behavior).
    • Document classes with JSDoc or comments for clarity.