TypeScript Object-Oriented Programming (OOP) Concepts
Classes
TypeScript Classes
A class in TypeScript is a blueprint for creating objects. It defines properties and methods that the object can use.
Syntax to Declare a Class
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
displayInfo(): void {
console.log(`Name: ${this.name}, Age: ${this.age}`);
}
}
Creating an Object
let person1 = new Person("John", 30);
person1.displayInfo(); // Output: Name: John, Age: 30
Object Initialization Objects can be initialized in different ways:
By Reference Variable
let person2: Person = person1;
person2.displayInfo(); // Output: Name: John, Age: 30
By Method
class Person {
constructor(public name: string, public age: number) {}
static createPerson(name: string, age: number): Person {
return new Person(name, age);
}
}
let person3 = Person.createPerson("Alice", 25);
person3.displayInfo(); // Output: Name: Alice, Age: 25
By Constructor
let person4 = new Person("Eve", 22);
person4.displayInfo(); // Output: Name: Eve, Age: 22
Getters and Setters
You can use getters and setters to define special methods that control access to object properties.
class Person {
private _age: number;
constructor(public name: string, age: number) {
this._age = age;
}
get age(): number {
return this._age;
}
set age(newAge: number) {
if (newAge >= 0) {
this._age = newAge;
} else {
console.log("Age cannot be negative");
}
}
}
let person5 = new Person("Bob", 30);
console.log(person5.age); // Output: 30
person5.age = 35;
console.log(person5.age); // Output: 35
person5.age = -5; // Output: Age cannot be negative
Objects
What Are Objects in TypeScript?
An object in TypeScript is an instance of a class or a custom data structure that can hold properties and methods.
let person = {
name: "John",
age: 30
};
Property Modifiers in Objects
Optional Property
let person = {
name: "John",
age?: number // Optional
};
Readonly Property
let person = {
readonly name: "John",
age: 30
};
Declaring a Variable that Holds an Object
let person: { name: string, age: number } = { name: "John", age: 30 };
Object vs. Object in TypeScript
- Object refers to the general object type.
{}
refers to an object without any specific properties.
let obj1: Object = {};
let obj2: {} = {};
Empty Type in TypeScript
An empty type {}
is a type with no properties.
let emptyObj: {} = {};
Access Modifiers
What Are Access Modifiers?
Access modifiers control the visibility of class members (properties or methods).
Public Access Modifier
A property or method with the public modifier can be accessed from anywhere.
class Person {
public name: string;
constructor(name: string) {
this.name = name;
}
}
let person = new Person("John");
console.log(person.name); // Output: John
Private Access Modifier
A property or method with the private modifier can only be accessed within the class.
class Person {
private name: string;
constructor(name: string) {
this.name = name;
}
displayName() {
console.log(this.name); // Can access private property
}
}
let person = new Person("John");
// console.log(person.name); // Error: Property 'name' is private and only accessible within class 'Person'.
person.displayName(); // Output: John
Protected Access Modifier
A property or method with the protected modifier can be accessed within the class and by subclasses.
class Employee extends Person {
protected position: string;
constructor(name: string, position: string) {
super(name);
this.position = position;
}
displayPosition() {
console.log(this.position); // Can access protected property
}
}
let employee = new Employee("Jane", "Developer");
employee.displayPosition(); // Output: Developer
Readonly Modifier
The readonly modifier makes properties immutable.
class Person {
readonly name: string;
constructor(name: string) {
this.name = name;
}
}
let person = new Person("John");
// person.name = "Alice"; // Error: Cannot assign to 'name' because it is a read-only property.
Static Methods and Properties
Static Methods
Static methods are called on the class itself, not on instances.
class MathOperations {
static add(a: number, b: number): number {
return a + b;
}
}
console.log(MathOperations.add(2, 3)); // Output: 5
Static Properties
Static properties are shared by all instances of a class.
class Counter {
static count: number = 0;
static increment() {
this.count++;
}
}
Counter.increment();
console.log(Counter.count); // Output: 1
as
Keyword
Different Types of Keywords in TypeScript
The as
keyword is used for type assertions.
let value: any = "Hello, world!";
let length: number = (value as string).length;
console.log(length); // Output: 13
this
Keyword
The this
keyword refers to the current instance of the class.
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
greet() {
console.log(`Hello, ${this.name}`);
}
}
let person = new Person("John");
person.greet(); // Output: Hello, John
Function Declaration Keywords
TypeScript uses function
to declare a function.
function greet(name: string): void {
console.log(`Hello, ${name}`);
}
Data Type Keywords
TypeScript provides types like string
, number
, boolean
, etc., for variable declaration.
let age: number = 25;
let name: string = "John";
Variable Declaration Keywords
TypeScript allows let
, const
, and var
for variable declarations.
let person = "John";
const age = 30;
as
Keyword in TypeScript
As mentioned, the as
keyword is used for type assertions, which tells the compiler to treat a value as a specific type.
let value: unknown = "Hello!";
let strLength: number = (value as string).length;
Inheritance
Types of Inheritance Single Inheritance A class can inherit from only one class.
class Animal {
sound(): void {
console.log("Some sound");
}
}
class Dog extends Animal {
sound(): void {
console.log("Bark");
}
}
let dog = new Dog();
dog.sound(); // Output: Bark
Hierarchical Inheritance
Multiple classes inherit from a single class.
class Animal {
sound(): void {
console.log("Some sound");
}
}
class Dog extends Animal {
sound(): void {
console.log("Bark");
}
}
class Cat extends Animal {
sound(): void {
console.log("Meow");
}
}
let dog = new Dog();
dog.sound(); // Output: Bark
let cat = new Cat();
cat.sound(); // Output: Meow
Multilevel Inheritance
A class inherits from another class, which is also inherited by another class.
class Animal {
sound(): void {
console.log("Some sound");
}
}
class Dog extends Animal {
sound(): void {
console.log("Bark");
}
}
class Puppy extends Dog {
sound(): void {
console.log("Puppy Bark");
}
}
let puppy = new Puppy();
puppy.sound(); // Output: Puppy Bark
Duck Typing
Duck typing refers to the concept where the type of an object is determined by its properties and methods, not its class.
interface Duck {
quack(): void;
}
class RealDuck implements Duck {
quack() {
console.log("Quack");
}
}
class FakeDuck {
quack() {
console.log("Fake Quack");
}
}
function makeQuack(duck: Duck) {
duck.quack();
}
makeQuack(new RealDuck()); // Output: Quack
makeQuack(new FakeDuck()); // Output: Fake Quack
Mixin
Mixins allow adding properties or methods to a class.
class Walker {
walk() {
console.log("Walking...");
}
}
class Runner {
run() {
console.log("Running...");
}
}
class Athlete implements Walker, Runner {
walk: () => void;
run: () => void;
}
Object.assign(Athlete.prototype, Walker.prototype, Runner.prototype);
let athlete = new Athlete();
athlete.walk(); // Output: Walking...
athlete.run(); // Output: Running...
Abstract Classes
Abstract classes cannot be instantiated and are meant to be inherited.
abstract class Animal {
abstract sound(): void;
}
class Dog extends Animal {
sound(): void {
console.log("Bark");
}
}
let dog = new Dog();
dog.sound(); // Output: Bark
Interfaces
Interfaces define the structure of an object or class.
interface Person {
name: string;
age: number;
}
let person: Person = { name: "John", age: 30 };
Generics
Generic Classes
class Box<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
let numberBox = new Box<number>(42);
console.log(numberBox.getValue()); // Output: 42
Generic Interfaces
interface Container<T> {
value: T;
}
let container: Container<string> = { value: "Hello" };
Decorators
Decorators are special types of declarations that can be attached to classes, methods, or properties to modify their behavior.
function log(target: any, key: string) {
console.log(`Property ${key} is being accessed`);
}
class Person {
@log
name: string;
constructor(name: string) {
this.name = name;
}
}
let person = new Person("John");
console.log(person.name); // Output: Property name is being accessed
Decorators Class Methods
function methodLog(target: any, methodName: string, descriptor: PropertyDescriptor) {
let originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Method ${methodName} called with arguments: ${args}`);
return originalMethod.apply(this, args);
};
}
class Person {
@methodLog
greet(name: string) {
console.log(`Hello, ${name}`);
}
}
let person = new Person();
person.greet("John"); // Output: Method greet called with arguments: [ 'John' ]
// Output: Hello, John