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.
- Syntax:
class ClassName { ... }.
Object: An instance of a class, created using the new keyword.
- Creation:
const obj = new ClassName().
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:
- Properties: Variables defined in the class (e.g.,
name: string). - Methods: Functions defined in the class (e.g.,
displayInfo(): string). - Static Members: Belong to the class, not instances, using
statickeyword.
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.
- public: Accessible everywhere (default).
- private: Accessible only within the class.
- protected: Accessible within the class and its subclasses.
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.
- Syntax: Add
public,private, orprotectedto constructor parameters. - Example:
constructor(public name: string)creates a publicnameproperty.
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.
- Syntax:
class Child extends Parent { ... }.
Method Overriding: Child class provides a specific implementation of a parent class method.
- Use
superto call parent methods.
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.
- Syntax:
abstract class ClassName { ... }.
Abstract Method: A method declared without implementation, requiring subclasses to provide it.
- Syntax:
abstract methodName(): returnType;.
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:
- Create the project structure.
- Install dependencies:
npm install. - Compile:
npm run build. - Run:
npm start.
Output:
Added Sashi to IT
kristal in IT, Salary: $60000, Employees in dept: 1
Developer in IT
Company: TechCorp
Description:
- Class Syntax/Members:
Departmentuses static and instance members;Employeedefines abstract methods. - Access Modifiers:
private salary,protected employees, andpublic nameenforce encapsulation. - Constructors/Parameter Properties: Used in
DepartmentandEmployeefor concise initialization. - Inheritance/Overriding:
DeveloperextendsEmployee, overridesaddEmployee. - Abstract Classes/Methods:
Employeeis abstract, requiringgetRoleimplementation.
8. What are common mistakes in TypeScript classes?
- Class Syntax/Members:
- Forgetting type annotations, reducing type safety.
- Declaring properties without initializing in constructor.
- Access Modifiers:
- Overusing
public, exposing sensitive data. - Misusing
protectedinstead ofprivatefor internal data.
- Overusing
- Constructors/Parameter Properties:
- Not calling
super()in subclass constructors, causing errors. - Overcomplicating constructors with redundant assignments.
- Not calling
- Inheritance/Overriding:
- Overriding methods without matching parent signatures.
- Not using
superto extend parent behavior.
- Abstract Classes/Methods:
- Forgetting to implement abstract methods in subclasses.
- Instantiating abstract classes, causing runtime errors.
- General:
- Ignoring TypeScript errors during compilation.
- Not leveraging static types for better maintainability.
9. What are best practices for TypeScript classes?
- Class Syntax/Members:
- Use explicit type annotations for all properties and methods.
- Define static members for shared data or utilities.
- Access Modifiers:
- Use
privatefor internal data;protectedfor subclass access. - Expose only necessary members as
public.
- Use
- Constructors/Parameter Properties:
- Use parameter properties to reduce boilerplate.
- Initialize all properties in the constructor.
- Inheritance/Overriding:
- Call
super()in subclass constructors and overridden methods. - Ensure overridden methods match parent signatures.
- Call
- Abstract Classes/Methods:
- Use abstract classes for shared logic with required subclass implementations.
- Clearly document abstract methods' expected behavior.
- General:
- Follow TypeScript naming conventions: CamelCase for classes, camelCase for members.
- Use
tscwithstrictmode (strict: trueintsconfig.json). - Test with edge cases (e.g., invalid inputs, subclass behavior).
- Document classes with JSDoc or comments for clarity.