<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nur Alam</title>
    <description>The latest articles on Forem by Nur Alam (@nur_alam_078).</description>
    <link>https://forem.com/nur_alam_078</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2673948%2Face422e8-a9f6-482b-ad09-6c88d1809d2b.jpg</url>
      <title>Forem: Nur Alam</title>
      <link>https://forem.com/nur_alam_078</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nur_alam_078"/>
    <language>en</language>
    <item>
      <title>Simplifying Object-Oriented Programming (OOP) Concepts with Real-Life Examples in TS</title>
      <dc:creator>Nur Alam</dc:creator>
      <pubDate>Fri, 17 Jan 2025 10:28:46 +0000</pubDate>
      <link>https://forem.com/nur_alam_078/simplifying-object-oriented-programming-oop-concepts-with-real-life-examples-in-ts-2epc</link>
      <guid>https://forem.com/nur_alam_078/simplifying-object-oriented-programming-oop-concepts-with-real-life-examples-in-ts-2epc</guid>
      <description>&lt;h2&gt;
  
  
  What is OOP?
&lt;/h2&gt;

&lt;p&gt;Object-Oriented Programming (OOP) is a programming paradigm (style used to write and organize code) that organizes and models software using objects. It promotes code reusability, modularity, and scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming Paradigms:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.Procedural Programming:&lt;/strong&gt;&lt;br&gt;
It follows a step-by-step approach using functions and procedures to solve problems. Code is executed in a linear flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Simple and easy to understand for small programs but harder to manage as complexity grows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// C Language
void greet() {
 printf("Hello!");
}
int main() {
 greet();
 return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.Functional Programming:&lt;/strong&gt;&lt;br&gt;
It focuses on pure functions and avoids changing data or state. Functions are treated as first-class citizens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Improves code predictability and testability by avoiding side effects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Javascript
 const add = (a, b) =&amp;gt; a + b;
console.log(add(2, 3)); // Output: 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3.Declarative Programming:&lt;/strong&gt;&lt;br&gt;
It focuses on what needs to be done rather than how to do it. The logic is handled by the underlying system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Simplifies complex operations by abstracting logic, making code more readable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//SQL
 SELECT name FROM users WHERE age &amp;gt; 18;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.Object-Oriented Programming (OOP):&lt;/strong&gt;&lt;br&gt;
It organizes code into objects with properties and methods to model real-world entities. It promotes code reusability and modularity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Simplifies complex systems through abstraction and makes maintenance easier with modular code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//JS
class Animal {
 speak() {
 console.log("The animal makes a sound");
 }
}
const dog = new Animal();
dog.speak();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.Event-Driven Programming:&lt;/strong&gt;&lt;br&gt;
The program responds to user actions or system events through event handlers. It’s common in GUI and web development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Improves user interaction by responding dynamically to events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//JS
 document.getElementById("btn").onclick = () =&amp;gt; alert("Button clicked!");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Object-Oriented Programming (OOP):
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.Inheritance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inheritance allows a class (child/subclass) to acquire properties and methods from another class (parent/superclass). This helps reuse code and extend functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Encourages code reusability and simplifies code maintenance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Parent Class: Person
class Person {
 constructor(public name: string, public age: number) {}
 introduce() {
 console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old.`);
 }
}
// Child Class: Student inherits from Person
class Student extends Person {
 constructor(name: string, age: number, public grade: string) {
 super(name, age); // Calls the Person constructor to set name age
 }
 study() {
 console.log(`${this.name} is studying in grade ${this.grade}.`);
 }
}
// Creating an instance of Student
const student1 = new Student("Alice", 20, "A");
student1.introduce(); // Inherited method → Output: Hi, I'm Alice and I'm 20 years old.
student1.study(); // Child's own method → Output: Alice is studying in grade A.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.Polymorphism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Polymorphism allows the same method to behave differently based on the object calling it. It helps write flexible and reusable code by using one method for many types of objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Increases flexibility and scalability by allowing one interface to support different data types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person {
 speak(): void {
 console.log("Person is speaking.");
 }
}
class Student extends Person {
 speak(): void {
 console.log("Student is studying.");
 }
}
class Teacher extends Person {
 speak(): void {
 console.log("Teacher is teaching.");
 }
}
function introduce(person: Person): void {
 person.speak();
}
const student = new Student();
const teacher = new Teacher();
introduce(student); // Output: Student is studying.
introduce(teacher); // Output: Teacher is teaching.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3.Abstraction:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Abstraction in OOP hides complex implementation details and only shows essential features to the user. It simplifies the code by focusing on what an object does instead of how it does it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Reduces complexity by focusing on high-level functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abstract class Animal {
 abstract makeSound(): void; // Abstract method (no implementation)
 sleep(): void {
 console.log("Sleeping…");
 }
}
class Dog extends Animal {
 makeSound(): void {
 console.log("Bark!");
 }
}
const dog = new Dog();
dog.makeSound(); // Output: Bark!
dog.sleep(); // Output: Sleeping…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.Encapsulation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Encapsulation in OOP is the process of bundling data (properties) and methods (functions) into a single unit (class) and restricting direct access to some of the object’s components. This protects the internal state of an object and only allows controlled interaction through public methods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Protects object integrity by controlling how data is accessed and modified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person {
 private age: number; // Private property
 constructor(age: number) {
 this.age = age;
 }
 // Public method to access the private property
 getAge(): number {
 return this.age;
 }
 // Public method to modify the private property with a condition
 setAge(newAge: number): void {
 if (newAge &amp;gt; 0) {
 this.age = newAge;
 }
 }
}
const person = new Person(25);
console.log(person.getAge()); // Output: 25
person.setAge(30);
console.log(person.getAge()); // Output: 30
// person.age = 40; // ❌ Error: Cannot access private property
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Introduction to OOP Principles (SOLID):
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;S: Single Responsibility Principle&lt;/strong&gt; — A class should only have one responsibility.&lt;br&gt;
&lt;strong&gt;Benefit:&lt;/strong&gt; Improves code maintainability and reduces complexity by separating concerns.&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; A User class should only handle user data, not authentication.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User {
 constructor(public name: string, public email: string) {}
}
class AuthService {
 login(user: User) {
 console.log(`Logging in ${user.name}`);
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O: Open/Closed Principle&lt;/strong&gt; — Classes should be open for extension but closed for modification.&lt;br&gt;
&lt;strong&gt;Benefit:&lt;/strong&gt; Encourages extending functionality without changing existing code, reducing the risk of bugs.&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Extending a payment system without changing its core logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface PaymentMethod {
 pay(amount: number): void;
}
class CreditCard implements PaymentMethod {
 pay(amount: number): void {
 console.log(`Paid ${amount} with Credit Card.`);
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;L: Liskov Substitution Principle&lt;/strong&gt; — Subclasses should replace base classes without breaking functionality.&lt;br&gt;
&lt;strong&gt;Benefit:&lt;/strong&gt; Ensures reliability when extending classes, preventing unexpected behavior.&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Replacing a base Bird with a Sparrow without issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Bird {
 fly(): void {
 console.log("Flying");
 }
}
class Sparrow extends Bird {}
const bird: Bird = new Sparrow();
bird.fly();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;I: Interface Segregation Principle&lt;/strong&gt; — Avoid forcing classes to implement unused methods.&lt;br&gt;
&lt;strong&gt;Benefit:&lt;/strong&gt; Simplifies class design and avoids unnecessary dependencies.&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Split interfaces for different user roles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Printer {
 print(): void;
}
interface Scanner {
 scan(): void;
}
class AllInOnePrinter implements Printer, Scanner {
 print(): void {
 console.log("Printing document");
 }
 scan(): void {
 console.log("Scanning document");
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;D: Dependency Inversion Principle&lt;/strong&gt; — High-level modules should depend on abstractions, not concrete implementations.&lt;br&gt;
&lt;strong&gt;Benefit:&lt;/strong&gt; Promotes flexibility and makes systems easier to refactor and maintain&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Using interfaces instead of direct class dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Database {
 connect(): void;
}
class MySQL implements Database {
 connect(): void {
 console.log("Connected to MySQL");
 }
}
class App {
 constructor(private db: Database) {}
 start() {
 this.db.connect();
 }
}
const app = new App(new MySQL());
app.start();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Important Topics:
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Class with Parameter Properties:
&lt;/h2&gt;

&lt;p&gt;In OOP, a class is a blueprint or template for creating objects. It defines the properties (attributes) and behaviors (methods) that the objects created from the class will have.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Without Parameter Properties
class PersonWithoutPP {
 private name: string; //Can't modify from outside
 private age: number;
 constructor(name: string, age: number) {
 this.name = name; // Manual assignment
 this.age = age;
 }
 greet(): void {
 console.log(`Hello, my name is ${this.name}.`);
 }
}
const personA = new PersonWithoutPP("Alice", 25);
personA.greet(); // Output: Hello, my name is Alice
// With Parameter Properties (Simpler)
class PersonWithPP {
 constructor(private name: string, private age: number) {} // Automatic assignment
 greet(): void {
 console.log(`Hello, my name is ${this.name}`);
 }
}
const personB = new PersonWithPP("Bob", 30);
personB.greet(); // Output: Hello, my name is Bob
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Typeof and In Guard:
&lt;/h2&gt;

&lt;p&gt;The typeof type guard is used to narrow down the type of a variable based on its type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function greet(person: string | number) {
 if (typeof person === "string") {
 console.log(`Hello, ${person}!`); // If person is a string
 } else {
 console.log(`Hello, number ${person}!`); // If person is a number
 }
}
greet("Alice"); // Output: Hello, Alice!
greet(25); // Output: Hello, number 25!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The in type guard is used to check if a specific property exists in an object, helping to narrow down the type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Bird {
 fly(): void;
}
interface Fish {
 swim(): void;
}
function move(animal: Bird | Fish) {
 if ("fly" in animal) {
 animal.fly(); // If it's a Bird, it will fly
 } else {
 animal.swim(); // If it's a Fish, it will swim
 }
}
const bird: Bird = { fly: () =&amp;gt; console.log("Flying!") };
const fish: Fish = { swim: () =&amp;gt; console.log("Swimming!") };
move(bird); // Output: Flying!
move(fish); // Output: Swimming!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  InstanceOf TypeGuard:
&lt;/h2&gt;

&lt;p&gt;The instanceOf operator is used to check if an object is an instance of a particular class or constructor function. It helps TypeScript narrow down the type of an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Animal {
 sound() {
 console.log("Animal sound");
 }
}
class Dog extends Animal {
 sound() {
 console.log("Bark");
 }
}
class Cat extends Animal {
 sound() {
 console.log("Meow");
 }
}
function makeSound(animal: Animal) {
 if (animal instanceof Dog) {
 animal.sound(); // If it's a Dog, we call Dog's sound()
 } else if (animal instanceof Cat) {
 animal.sound(); // If it's a Cat, we call Cat's sound()
 } else {
 animal.sound(); // If it's any other Animal, we call its sound
 }
}
const myDog = new Dog();
const myCat = new Cat();
const genericAnimal = new Animal();
makeSound(myDog); // Output: Bark
makeSound(myCat); // Output: Meow
makeSound(genericAnimal); // Output: Animal sound
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Access Modifier(Public, Private, Protected):
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Public:&lt;/strong&gt; Accessible anywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Private:&lt;/strong&gt; Accessible only within the class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protected:&lt;/strong&gt; Accessible within the class and subclasses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Employee {
 // public, can be accessed anywhere
 public name: string;
 // private, can only be accessed inside this class
 private salary: number;
 // protected, can be accessed inside this class and subclasses
 protected position: string;
 constructor(name: string, salary: number, position: string) {
 this.name = name;
 this.salary = salary;
 this.position = position;
 }
 // public method
 public displayInfo(): void {
 console.log(`Name: ${this.name}, Position: ${this.position}`);
 }
 // private method
 private calculateBonus(): number {
 return this.salary * 0.1;
 }
 // protected method
 protected showSalary(): void {
 console.log(`Salary: ${this.salary}`);
 }
}
class Manager extends Employee {
 constructor(name: string, salary: number, position: string) {
 super(name, salary, position);
 }
 // Access protected method
 public displaySalary(): void {
 this.showSalary(); // Works because showSalary is protected
 }
}
const emp = new Employee("John", 50000, "Developer");
console.log(emp.name); // public access
emp.displayInfo(); // public method works
// const emp2 = new Employee("John", 50000, "Developer");
// emp2.salary; // Error: 'salary' is private
const mgr = new Manager("Alice", 70000, "Manager");
mgr.displayInfo(); // public method works
mgr.displaySalary(); // protected method works in subclass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getter &amp;amp; Setter:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Employee {
 private _name: string;
 constructor(name: string) {
 this._name = name;
 }
 // Getter for _name
 get name(): string {
 return this._name;
 }
 // Setter for _name
 set name(newName: string) {
 this._name = newName;
 }
}
const emp = new Employee("John");
console.log(emp.name); // Output: John
emp.name = "Alice";
console.log(emp.name); // Output: Alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Statics in OOP:
&lt;/h2&gt;

&lt;p&gt;Static means a property or method belongs to the class itself, not to its instances, and is shared across all objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Counter {
 static count: number = 0; // Shared across all instances
 increment() {
 Counter.count++; // Increases the shared 'count'
 }
}
const obj1 = new Counter();
const obj2 = new Counter();
obj1.increment(); // Counter.count becomes 1
obj2.increment(); // Counter.count becomes 2
console.log(Counter.count); // Output: 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interfaces for Abstraction
&lt;/h2&gt;

&lt;p&gt;Interfaces define a contract that classes must follow, ensuring consistency without implementation details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Animal {
 speak(): void;
}
class Cat implements Animal {
 speak(): void {
 console.log("Meow");
 }
}
const cat = new Cat();
cat.speak(); // Output: Meow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Method Overloading
&lt;/h2&gt;

&lt;p&gt;Method overloading allows a class to define multiple methods with the same name but different parameter types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Printer {
 print(value: string): void;
 print(value: number): void;
 print(value: any): void {
 console.log(value);
 }
}
const printer = new Printer();
printer.print("Hello"); // Output: Hello
printer.print(123); // Output: 123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Composition Over Inheritance
&lt;/h2&gt;

&lt;p&gt;Composition allows building complex behavior by combining simple, reusable components rather than relying on inheritance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Engine {
 start() {
 console.log("Engine started");
 }
}
class Car {
 constructor(private engine: Engine) {}

 drive() {
 this.engine.start();
 console.log("Car is driving");
 }
}
const car = new Car(new Engine());
car.drive(); // Output: Engine started \n Car is driving
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Decorators
&lt;/h2&gt;

&lt;p&gt;Special functions that modify classes or methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Log(target: any, key: string) {
 console.log(`Calling ${key}`);
}
class Person {
 @Log
 sayHello() {
 console.log("Hello!");
 }
}
const person = new Person();
person.sayHello(); 
// Output: Calling sayHello \n Hello!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use of super Keyword
&lt;/h2&gt;

&lt;p&gt;super calls methods from a parent class inside a child class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Animal {
 move() {
 console.log("Animal moves");
 }
}
class Dog extends Animal {
 move() {
 super.move();
 console.log("Dog runs");
 }
}
const dog = new Dog();
dog.move(); // Output: Animal moves \n Dog runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mixins
&lt;/h2&gt;

&lt;p&gt;Mixins allow sharing functionality between classes without inheritance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Constructor&amp;lt;T = {}&amp;gt; = new (…args: any[]) =&amp;gt; T;
function CanFly&amp;lt;TBase extends Constructor&amp;gt;(Base: TBase) {
 return class extends Base {
 fly() {
 console.log("Flying");
 }
 };
}
class Bird {}
const FlyingBird = CanFly(Bird);
const bird = new FlyingBird();
bird.fly(); // Output: Flying
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understand OOP and SOLID with a Real-Life Story: The Bakery Business 🍰
&lt;/h2&gt;

&lt;p&gt;Imagine you’re opening a bakery!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Class and Object&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Class:&lt;/strong&gt; Think of a “Cake Recipe.” It has ingredients and steps but isn’t a cake yet.&lt;br&gt;
&lt;strong&gt;Object:&lt;/strong&gt; When you follow the recipe and bake a cake, that’s the Object!&lt;br&gt;
&lt;strong&gt;2. Encapsulation&lt;/strong&gt;&lt;br&gt;
You have a secret frosting recipe. You keep it in a locked drawer so no one can change it. Customers can enjoy the cake but can’t access the secret recipe.&lt;br&gt;
Encapsulation protects important information by hiding it.&lt;br&gt;
&lt;strong&gt;3. Inheritance&lt;/strong&gt;&lt;br&gt;
You make a basic chocolate cake. Then, you create a “Chocolate Lava Cake” by adding some gooey chocolate inside. You didn’t start from scratch — you just extended the chocolate cake!&lt;br&gt;
Inheritance lets you reuse and expand on existing ideas.&lt;br&gt;
&lt;strong&gt;4. Polymorphism&lt;/strong&gt;&lt;br&gt;
A customer asks for a “Cake.” Some want chocolate, others want vanilla. You know how to make both, but they all just ask for a cake!&lt;br&gt;
Polymorphism means one command works in different ways.&lt;br&gt;
&lt;strong&gt;5. Abstraction&lt;/strong&gt;&lt;br&gt;
Customers only see the delicious cakes on display. They don’t need to know how the oven works or how the dough rises.&lt;br&gt;
Abstraction hides complex processes and shows only the necessary parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding SOLID Principles
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Single Responsibility Principle (SRP)&lt;/strong&gt;&lt;br&gt;
A “CakeMaker” only handles baking cakes, not decorating them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Open/Closed Principle (OCP)&lt;/strong&gt;&lt;br&gt;
You can add a new cake flavor without changing the base recipe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Liskov Substitution Principle (LSP)&lt;/strong&gt;&lt;br&gt;
If a “ChocolateCake” is a type of “Cake,” customers should enjoy it just like any other cake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Interface Segregation Principle (ISP)&lt;/strong&gt;&lt;br&gt;
Your bakers only need cake recipes, while cashiers only need the register instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Dependency Inversion Principle (DIP)&lt;/strong&gt;&lt;br&gt;
Your bakery depends on suppliers for ingredients but not on which supplier it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding Object-Oriented Programming (OOP) and SOLID Principles doesn’t have to be intimidating. By relating these concepts to something as simple and enjoyable as running a bakery, we can see how these principles apply to real-world scenarios. OOP helps us structure our code efficiently, making it reusable and easy to manage, while SOLID principles guide us in writing clean, scalable, and maintainable software.&lt;/p&gt;

&lt;p&gt;Just like a bakery thrives on well-organized recipes and processes, your software projects can thrive with strong design principles. So, whether you’re baking cakes or building applications, remember that the right foundation leads to sweet success! 🍰💻&lt;/p&gt;

&lt;p&gt;Happy Coding! 🚀&lt;/p&gt;

</description>
      <category>oop</category>
      <category>typescript</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🚀 TypeScript Fundamentals: A Complete Guide for Beginners</title>
      <dc:creator>Nur Alam</dc:creator>
      <pubDate>Thu, 16 Jan 2025 16:38:46 +0000</pubDate>
      <link>https://forem.com/nur_alam_078/typescript-fundamentals-a-complete-guide-for-beginners-b4i</link>
      <guid>https://forem.com/nur_alam_078/typescript-fundamentals-a-complete-guide-for-beginners-b4i</guid>
      <description>&lt;h2&gt;
  
  
  📖 What is TypeScript?
&lt;/h2&gt;

&lt;p&gt;TypeScript is a strongly typed, object-oriented programming language that builds on JavaScript by adding static types.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚠️ Limitations of JavaScript
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dynamically Typed Language: We can put a string or number or array or object on the same variable which isn’t a feasible thing. Also checking the type errors in large-scale apps is very difficult.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let a = 'Nur Alam';
a=[1,2,3]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;JavaScript supports object-oriented programming through prototypes and ES6 classes.&lt;/li&gt;
&lt;li&gt;In JS we find the errors in runtime rather compile time.&lt;/li&gt;
&lt;li&gt;When working on a large application with JS then it’s difficult to maintain a large codebase, it's hard to find bugs, and catch errors only in runtime.&lt;/li&gt;
&lt;li&gt;If we need to convert the code to support old browser then it will be a issue. But typescript can be transpiled into an older version of JS easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;** Browsers don't natively support TypeScript. We need to convert it to JS &lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ✅ Why Use TypeScript? (Benefits)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Supports older browser&lt;/li&gt;
&lt;li&gt;Type safety&lt;/li&gt;
&lt;li&gt;Increase Productivity&lt;/li&gt;
&lt;li&gt;Fewer Bugs and less testing&lt;/li&gt;
&lt;li&gt;TS has all types of JS( Number, String, Boolean, Null, Undefined, Object, Symbol) and has some own types as well (Interface, Void, Array, Tuple, Enum, Union, Intersection).

&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Drawbacks of TypeScript
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Type Complexities ( Have to define types for small projects)&lt;/li&gt;
&lt;li&gt;Limited Library support (Have to take additional library support sometimes)&lt;/li&gt;
&lt;li&gt;Over-engineering in type design can complicate small projects.&lt;/li&gt;
&lt;li&gt;Migration Challenge (Convert existing JS to TS)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🛠️ Installing and Running TypeScript
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Install Typescript:&lt;/strong&gt; &lt;code&gt;npm i -g typescript&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run Typescript Code:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize Typescript Config:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tsc --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Go to tsconfig.json and change the rootDir and outDir with uncomment to your path. Ex:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"rootDir": "./app/src/",  // TS Files
"outDir": "./app/dist/",   //Output directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Open the terminal and run “tsc”. It will compile ts file to js. You can set compile version in “target” of tsconfig.json. For example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"target" : "ES5",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;*&lt;em&gt;**To easily run ts file, we can use ts-node-dev npm package. Here’s the process:&lt;/em&gt;*&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Install
npm i -g ts-node-dev
//Run
ts-node-dev --respawn --transpile-only server.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  🔢 Primitive and Non-Primitive Types
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Primitive:&lt;/strong&gt; number, string, boolean, null, undefined, symbol&lt;br&gt;
&lt;strong&gt;Non primitive:&lt;/strong&gt; Array, Tuple, Object&lt;/p&gt;

&lt;p&gt;** In JS, Objects are non-primitive. TS has array and objects both data types. We don’t get data type in TS in runtime, we get it when we compile.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🆚 Implicit vs Explicit Data Typing
&lt;/h2&gt;

&lt;p&gt;When we define type then it’s explicit.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🔠 Basic Data Types with Examples
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//string
let firstName: string = 'Nur'
//number
let roll: number = 123
//boolean
let isAdmin: boolean = true
//undefined
let x: undefined = undefined
//null
let y:null = null
//any. Can be any data type. Isn't recommended to use.
let z: any = 'Any'
//Array
let friends: string[] = ['Alice', 'Rachel']
//tuple -&amp;gt;Special type of array which maintains type order
let coordinates: [number, number] = [5,5]
//Object
const user: {
   firstName: string;
   middleName?: string; //Optional
   lastName: string;
} = {
   firstName: 'Nur',
   lastName: 'Alam'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📦 Object Literals
&lt;/h2&gt;

&lt;p&gt;It defines its own type. In below example company name is fixed so we can define a new type for that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const user: {
   company: 'Google', // Literal Type
   firstName: string;
   middleName?: string; //Optional
   lastName: string;
} = {
   company: 'Google',
   firstName: 'Nur',
   lastName: 'Alam'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🏗️ Functions in TypeScript
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Normal Function with types and predefined value
function add(num1: number, num2: number = 10): number {
 return num1 + num2;
}


//Arrow Function
const add = (num1: number, num2: number): number =&amp;gt; num1 + num2;


//Method -&amp;gt; A function inside JS Object
const user = {
 name: "Nur",
 balance: 0,
 addBalance(balance: number): number {
   return this.balance + balance;
 },
};


//Callback Function - A callback function is a function passed as an argument to another function and is executed later within that function.
//Here a arrow function is passed in map function
const num: number[] = [1, 2, 3];
const doubleNum: number[] = num.map((elem: number): number =&amp;gt; elem * 2);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🔄 Spread &amp;amp; Rest Operators
&lt;/h2&gt;

&lt;p&gt;​​Spread operator expands elements, while the rest operator collects arguments into an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Spread Operator
const arr1: number[] = [1, 2, 3];
const arr2: number[] = [4, 5, 6];


const combineArr: number[] = [...arr1, ...arr2];


//Rest Operator -&amp;gt; Used to collect multiple arguments into a single array.
const employee = (...employee: string[]) =&amp;gt; {
 employee.forEach((em: string) =&amp;gt; console.log(`Onboard ${em}`));
};


employee("Nur", "Abul", "Rimon");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🏗️ Destructuring in TS:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Object Destructuring
const user = {
 id: 123,
 name: {
   firstName: 'Nur',
   lastName: 'Alam',
 }
}
//Destructuring id as userID ( Name Alias) and firstName
const {id: userID, name: { firstName }} = user;


//Array Destructure
const friends = ["Joy", "Akash", "Karim", "Latif", "Opu" ]
//Destructuring Karim as bestfriend and latif, opu in rest
const [,,bestFriend, ...rest] = friends
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🔄 Type Alias
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Type Alias in object
type User = {
 firstName: string;
 middleName?: string; //Optional
 lastName: string;
}
const user1: User = {
 firstName: 'Nur',
 lastName: 'Alam'
}


//Type Alias in Function
type Add = (num1: number, num2: number) =&amp;gt; number
const add: Add = (num1, num2) =&amp;gt; num1+num2;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🔗 Union, Intersection, Nullish Coalescing Operator
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Ternary Operator
const hasPassed = mark &amp;gt;=40 ? "Passed" : "Failed";


//Union
const user = User1 | User2 // Can be either of User type
//Intersection
const user = User1 &amp;amp; User2 // Combination of both the type and will contain all field


// Nullish Coalesing Operator
// Used when need to make decision based on null or undefined
const isAdmin = null;
const userType = isAdmin ?? "Normal User";


//Optional Chaining
const isPassed = student?.marks ?? "Didn't attend exam"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🚫 Never, Unknown, Nullable Types
&lt;/h2&gt;

&lt;p&gt;never is used for functions that never return or reach the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function throwError(message: string): never {
  throw new Error(message);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;unknown represents a value with an unknown type and requires type checking before use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let data: unknown = "Hello";
if (typeof data === "string") {
  console.log(data.toUpperCase());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nullable types (null and undefined) allow variables to have no value or be unassigned.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let name: string | null = null;
let age: number | undefined;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🧐 Type Assertion &amp;amp; Type Narrowing
&lt;/h2&gt;

&lt;p&gt;Type Assertion tells TypeScript to treat a value as a specific type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let value: unknown = "Hello, TypeScript!";
let strLength: number = (value as string).length;
console.log(strLength); // Output: 18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Type Alias vs Interface:
&lt;/h2&gt;

&lt;p&gt;The interface is primarily used to define the structure of objects and is extendable using the extends keyword, making it ideal for object-oriented designs. It also supports declaration merging, allowing multiple declarations of the same interface to automatically combine. &lt;/p&gt;

&lt;p&gt;On the other hand, type is more flexible and can define primitives, unions, tuples, and object types but does not support declaration merging. It uses the intersection operator (&amp;amp;) to combine types. For example, using an interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Person {
  name: string;
  age: number;
}
interface Employee extends Person {
  salary: number;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whereas with a type alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type PersonType = { name: string; age: number; };
type EmployeeType = PersonType &amp;amp; { salary: number; };

Merging
interface User {
  name: string;
}

interface User {
  age: number;
}

// Result: { name: string; age: number; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🛠️ Generics
&lt;/h2&gt;

&lt;p&gt;Generics in TypeScript allow us to create reusable components that can work with a variety of data types while maintaining type safety. Instead of specifying a fixed type, generics use type parameters that are specified when the function, class, or interface is used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Generic Array
type GenericArray&amp;lt;T&amp;gt; = Array&amp;lt;T&amp;gt;;
//Same as GenericArray[number]
const roll: GenericArray&amp;lt;number&amp;gt; = [1, 2, 3];

//Generic Object
const user: GenericArray&amp;lt;{ name: string, age: number}&amp;gt; = [
 {
   name: "Nur",
   age: 25
 }
]
//Generic Tuple
type GenericTuple&amp;lt;X,Y&amp;gt; = [X,Y]
const user: GenericTuple&amp;lt;string, string&amp;gt; = ["Mr. X", "Admin"]
//Generic with interface
interface ApiResponse&amp;lt;T&amp;gt; {
  status: number;
  data: T;
}

const userResponse: ApiResponse&amp;lt;{ name: string; age: number }&amp;gt; = {
  status: 200,
  data: { name: "Alice", age: 25 },
};

const productResponse: ApiResponse&amp;lt;string[]&amp;gt; = {
  status: 200,
  data: ["Laptop", "Phone"],
};

//Generic in Function
const createGenericArr = &amp;lt;T&amp;gt;(param: T): T[] =&amp;gt;{
 return [param];
}

const result = createGenericArr&amp;lt;string&amp;gt;("Hello");

//Generic in tuple
const genericTuple =&amp;lt;T,Q&amp;gt;(param1: T, param2: Q): [T,Q]=&amp;gt;{
 return [param1, param2];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🚧 Constraints:
&lt;/h2&gt;

&lt;p&gt;Constraints in TypeScript limit the types that can be used in generics to ensure type safety.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function printLength&amp;lt;T extends { length: number }&amp;gt;(item: T) {
  console.log(item.length);
}

printLength("Hello");      // ✅ Works (string has length)
printLength([1, 2, 3]);    // ✅ Works (array has length)
// printLength(123);       // ❌ Error (number has no length)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🔑 keyof Constraint
&lt;/h2&gt;

&lt;p&gt;Limits a generic type to the keys of another type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Person {
  name: string;
  age: number;
}

function getValue&amp;lt;T, K extends keyof T&amp;gt;(obj: T, key: K) {
  return obj[key];
}

const person: Person = { name: "Alice", age: 25 };
console.log(getValue(person, "name")); // ✅ Output: Alice
// getValue(person, "height");         // ❌ Error: "height" is not a key of Person
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  ⚡ Conditional Types:
&lt;/h2&gt;

&lt;p&gt;Conditional types allow you to create types that depend on a condition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type IsString&amp;lt;T&amp;gt; = T extends string ? "Yes" : "No";

type Test1 = IsString&amp;lt;string&amp;gt;;  // "Yes"
type Test2 = IsString&amp;lt;number&amp;gt;;  // "No"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Mapped Types:
&lt;/h2&gt;

&lt;p&gt;Mapped types allow you to transform existing types by looping over their properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Person = {
  name: string;
  age: number;
};

// Make all properties optional
type PartialPerson = {
  [K in keyof Person]?: Person[K];
};

const person: PartialPerson = { name: "Alice" }; // `age` is optional
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  🛠️ Utility Types
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pick → Select specific properties from a type
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Person {
  name: string;
  age: number;
  address: string;
}

type NameAndAge = Pick&amp;lt;Person, "name" | "age"&amp;gt;;

const person: NameAndAge = { name: "Alice", age: 25 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Omit → Exclude specific properties from a type
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type WithoutAddress = Omit&amp;lt;Person, "address"&amp;gt;;

const personWithoutAddress: WithoutAddress = { name: "Bob", age: 30 };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Required → Make all properties mandatory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Product {
  id: number;
  description?: string;
}

type RequiredProduct = Required&amp;lt;Product&amp;gt;;

const product: RequiredProduct = { id: 1, description: "New product" };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Readonly → Make all properties immutable
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Car {
  model: string;
  year: number;
}

const car: Readonly&amp;lt;Car&amp;gt; = { model: "Tesla", year: 2023 };
// car.model = "BMW"; // ❌ Error: Cannot assign to 'model' because it is a read-only property
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Record → Create an object type with specified keys and value types
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type UserRole = "admin" | "user" | "guest";

const roles: Record&amp;lt;UserRole, string&amp;gt; = {
  admin: "Full Access",
  user: "Limited Access",
  guest: "Read-Only Access",
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Partial → Make all properties optional
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Profile {
  username: string;
  email: string;
}

type OptionalProfile = Partial&amp;lt;Profile&amp;gt;;

const userProfile: OptionalProfile = { username: "Nur" }; // `email` is optional
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Enum:
&lt;/h2&gt;

&lt;p&gt;Enums allow us to define a set of named constants. It makes code more readable and manageable when dealing with constant values  and&lt;br&gt;
enforces valid inputs over plain strings or numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT"
}

let move: Direction = Direction.Left;
console.log(move); // Output: "LEFT"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Template Literal Types:
&lt;/h2&gt;

&lt;p&gt;Template Literal Types build complex types using string literals and union types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type HttpMethod = "GET" | "POST";
type ApiRoute = "/users" | "/products";

type Endpoint = `${HttpMethod} ${ApiRoute}`;

const getUser: Endpoint = "GET /users";  // ✅
const invalid: Endpoint = "DELETE /users"; // ❌ Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;TypeScript offers powerful tools for building scalable and robust applications. It enhances JavaScript with static typing, better tooling, and modern features.&lt;/p&gt;

&lt;p&gt;Start using TypeScript today to write cleaner, safer, and more efficient code!&lt;/p&gt;

&lt;p&gt;Got questions or feedback? Drop a comment below! 👇&lt;/p&gt;

&lt;p&gt;Follow me to learn OOP in Typescript.&lt;/p&gt;

&lt;p&gt;Happy Coding! 🚀&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Comprehensive Redux Toolkit Notes for React Developers</title>
      <dc:creator>Nur Alam</dc:creator>
      <pubDate>Tue, 14 Jan 2025 14:48:13 +0000</pubDate>
      <link>https://forem.com/nur_alam_078/comprehensive-redux-toolkit-notes-for-react-developers-588a</link>
      <guid>https://forem.com/nur_alam_078/comprehensive-redux-toolkit-notes-for-react-developers-588a</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Redux Toolkit Notes 🚀
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;What is Redux?&lt;/strong&gt;&lt;br&gt;
Redux is a flexible state container for JS apps that manages our application state separately. It manages the application state in a single store, making it easier to handle complex state logic across the entire app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Redux?&lt;/strong&gt;&lt;br&gt;
In normal flow, we need to do prop drilling to pass states in between components. Some levels don’t need the states here, which is a burden. Also uplifting a state for large medium apps isn’t a scalable solution as it requires structural changes. That’s why we need redux to manage states. All the states here are kept in store and whichever component needs that they can just subscribe to that store. Redux ensures predictable state management, easier debugging, and improved scalability by enforcing a unidirectional data flow.&lt;/p&gt;
&lt;h2&gt;
  
  
  Core Redux Components:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Action:&lt;/strong&gt; An object that describes what happened. It typically contains a type and an optional payload. (A command)&lt;br&gt;
&lt;strong&gt;Dispatch:&lt;/strong&gt; A function used to send actions to the store to update the state. (A event occurring)&lt;br&gt;
&lt;strong&gt;Reducer:&lt;/strong&gt; A pure function that takes the current state and an action, then returns a new state. (Function that triggers when action dispatched)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing:&lt;/strong&gt; &lt;code&gt;npm i @reduxjs/toolkit react-redux&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Redux Workflow:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Creating a Slice:&lt;/strong&gt;&lt;br&gt;
A slice is a collection of Redux reducer logic and actions for a single feature. The prepare callback allows US to customize the action payload before it reaches the reducer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice, nanoid } from "@reduxjs/toolkit";

const postSlice = createSlice({
 name: "posts",
 initialState: [],
 reducers: {
   addPost: {
     reducer: (state, action) =&amp;gt; {
       state.push(action.payload);
     },
     prepare: (title, content) =&amp;gt; ({
       payload: { id: nanoid(), title, content },
     }),
   },
   deletePost: (state, action) =&amp;gt; {
     return state.filter((post) =&amp;gt; post.id != action.payload);
   },
 },
});

export const { addPost, deletePost } = postSlice.actions;

export default postSlice.reducer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creating store:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { configureStore } from "@reduxjs/toolkit";
import postReducer from "../features/posts/postSlice";

export const store = configureStore({
   reducer: {
       posts: postReducer
   },
 });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Wrap with provider:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Provider } from "react-redux";
import { store } from "./app/store.jsx";

createRoot(document.getElementById("root")).render(
 &amp;lt;StrictMode&amp;gt;
   &amp;lt;Provider store={store}&amp;gt;
     &amp;lt;App /&amp;gt;
   &amp;lt;/Provider&amp;gt;
 &amp;lt;/StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use in Component:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const PostList = ({ onEdit }) =&amp;gt; {
 const posts = useSelector((state) =&amp;gt; state.posts);
 const dispatch = useDispatch();

 return (
   &amp;lt;div className="w-full grid grid-cols-1 gap-6 mt-12"&amp;gt;
     {posts.map((post) =&amp;gt; (
       &amp;lt;div key={post.id}&amp;gt;&amp;lt;/div&amp;gt;
     ))}
   &amp;lt;/div&amp;gt;
 );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Redux Browser Extension:&lt;/strong&gt; Redux DevTools&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const store = configureStore({
  reducer: rootReducer,
  devTools: process.env.NODE_ENV !== 'production',
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Async Operation in Redux (Redux Thunk):
&lt;/h2&gt;

&lt;p&gt;In Redux, asynchronous operations (like API calls) are handled using middleware because Redux by default only supports synchronous state updates. The most common middlewares for handling async operations are Redux Thunk, Redux Toolkit (RTK) with createAsyncThunk, and Redux Saga.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

// Fetch all posts
export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () =&amp;gt; {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts');
  return response.json();
});

// Initial State
const initialState = {
  posts: [],
  post: null,
  loading: false,
  error: null,
};

// Slice
const postsSlice = createSlice({
  name: 'posts',
  initialState,
  reducers: {},
  extraReducers: (builder) =&amp;gt; {
    builder
      // Fetch all posts
      .addCase(fetchPosts.pending, (state) =&amp;gt; {
        state.loading = true;
      })
      .addCase(fetchPosts.fulfilled, (state, action) =&amp;gt; {
        state.loading = false;
        state.posts = action.payload;
      })
      .addCase(fetchPosts.rejected, (state, action) =&amp;gt; {
        state.loading = false;
        state.error = action.error.message;
      })

      },
});

export default postsSlice.reducer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use Case:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchPosts, createPost, updatePost, deletePost } from './postsSlice';

const Posts = () =&amp;gt; {
  const dispatch = useDispatch();
  const { posts, loading, error } = useSelector((state) =&amp;gt;state.posts);

  useEffect(() =&amp;gt; {
    dispatch(fetchPosts());
  }, [dispatch]);

  const handleCreate = () =&amp;gt; {
    dispatch(createPost({ title: 'New Post', body: 'This is a new post' }));
  };

  if (loading) return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;;
  if (error) return &amp;lt;p&amp;gt;Error: {error}&amp;lt;/p&amp;gt;;

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Posts&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={handleCreate}&amp;gt;Create Post&amp;lt;/button&amp;gt;
     &amp;lt;/div&amp;gt;
  );
};

export default Posts;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Middleware&lt;/strong&gt;&lt;br&gt;
Middleware in Redux intercepts dispatched actions, allowing for logging, crash reporting, or handling async logic. Middleware lets us customize the dispatch process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const blogPostMiddleware = (storeAPI) =&amp;gt; (next) =&amp;gt; (action) =&amp;gt; {
  if (action.type === 'posts/publishPost') {
    const contentLength = action.payload.content.length;

    if (contentLength &amp;lt; 50) {
      console.warn('Post content is too short. Must be at least 50 characters.');
      return;
    }
    console.log('Publishing post:', action.payload.title);
  }
  return next(action);
};

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =&amp;gt; getDefaultMiddleware().concat(blogPostMiddleware),
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Selectors&lt;/strong&gt;&lt;br&gt;
Selectors help access specific parts of the state.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;export const selectCount = (state) =&amp;gt; state.counter.value;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;&lt;br&gt;
Handle errors effectively with proper state management.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;initialState: {
  items: [],
  status: 'idle',
  error: null,
},

.addCase(fetchData.rejected, (state, action) =&amp;gt; {
  state.status = 'failed';
  state.error = action.error.message;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  RTK Query (Simplified Data Fetching)
&lt;/h2&gt;

&lt;p&gt;RTK Query simplifies data fetching, caching, and synchronization. RTK Query automatically caches requests and avoids unnecessary refetching, improving performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up RTK Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

const api = createApi({
  reducerPath: 'api',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://jsonplaceholder.typicode.com' }),
  endpoints: (builder) =&amp;gt; ({
    getPosts: builder.query({
      query: () =&amp;gt; '/posts',
    }),
    getPostById: builder.query({
      query: (id) =&amp;gt; `/posts/${id}`,
    }),
    createPost: builder.mutation({
      query: (newPost) =&amp;gt; ({
        url: '/posts',
        method: 'POST',
        body: newPost,
      }),
    }),
    updatePost: builder.mutation({
      query: ({ id, ...updatedPost }) =&amp;gt; ({
        url: `/posts/${id}`,
        method: 'PUT',
        body: updatedPost,
      }),
    }),
    deletePost: builder.mutation({
      query: (id) =&amp;gt; ({
        url: `/posts/${id}`,
        method: 'DELETE',
      }),
    }),
  }),
});

export const {
  useGetPostsQuery,
  useGetPostByIdQuery,
  useCreatePostMutation,
  useUpdatePostMutation,
  useDeletePostMutation,
} = api;
export default api;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage in Components&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { 
  useGetPostsQuery, 
  useCreatePostMutation, 
  useUpdatePostMutation, 
  useDeletePostMutation 
} from './api';

const Blog = () =&amp;gt; {
  const { data: posts, error, isLoading } = useGetPostsQuery();
  const [createPost] = useCreatePostMutation();
  const [updatePost] = useUpdatePostMutation();
  const [deletePost] = useDeletePostMutation();

  if (isLoading) return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;;
  if (error) return &amp;lt;p&amp;gt;Error: {error.message}&amp;lt;/p&amp;gt;;

  const handleCreate = async () =&amp;gt; {
    await createPost({ title: 'New Post', body: 'Content of the post', userId: 1 });
  };

  const handleUpdate = async (id) =&amp;gt; {
    await updatePost({ id, title: 'Updated Title', body: 'Updated content' });
  };

  const handleDelete = async (id) =&amp;gt; {
    await deletePost(id);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;button onClick={handleCreate}&amp;gt;Create Post&amp;lt;/button&amp;gt;
      &amp;lt;ul&amp;gt;
        {posts.map((post) =&amp;gt; (
          &amp;lt;li key={post.id}&amp;gt;
            {post.title}
            &amp;lt;button onClick={() =&amp;gt; handleUpdate(post.id)}&amp;gt;Edit&amp;lt;/button&amp;gt;
            &amp;lt;button onClick={() =&amp;gt; handleDelete(post.id)}&amp;gt;Delete&amp;lt;/button&amp;gt;
          &amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};
export default Blog;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Immutable Updates with Immer
&lt;/h2&gt;

&lt;p&gt;Immer allows us to write logic that "mutates" state directly while keeping the updates immutable under the hood.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) =&amp;gt; {
      state.value += 1; // Mutates state directly (handled by Immer)
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mutate vs. Immutable
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mutate:&lt;/strong&gt; Changing the data directly. For example, modifying an object or array.&lt;br&gt;
&lt;strong&gt;Immutable:&lt;/strong&gt; Instead of modifying data directly, we create a new copy with the changes applied, leaving the original data untouched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Immer Works&lt;/strong&gt;&lt;br&gt;
Immer helps us write code that looks like we're mutating data (i.e., changing it directly), but it automatically keeps the changes immutable under the hood. This is useful for avoiding common bugs when dealing with immutable data structures in JavaScript.&lt;br&gt;
&lt;strong&gt;Example: Without Immer (mutation):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let state = { value: 0 };

// Mutating the state directly
state.value += 1; // This is mutation
console.log(state.value); // 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With Immer (immutability):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import produce from 'immer';

let state = { value: 0 };

// Using Immer's `produce` to "mutate" the state
const nextState = produce(state, draft =&amp;gt; {
  draft.value += 1; // Looks like mutation, but Immer keeps it immutable
});

console.log(state.value); // 0 (original state is unchanged)
console.log(nextState.value); // 1 (new state with the update)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes working with Redux (or any state management) easier because we don’t have to clone and update the state manually; Immer does it for us automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redux Persist:
&lt;/h2&gt;

&lt;p&gt;To persist Redux state across page refreshes, we can integrate Redux Persist. This will store your Redux state in local storage or session storage and reload it when the app is refreshed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;npm install redux-persist&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implement:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage'; 
// Defaults to localStorage
import { combineReducers } from 'redux';
import postReducer from './postSlice';

// Persist configuration
const persistConfig = {
  key: 'root',
  storage,
};

// Combine reducers (in case of multiple reducers)
const rootReducer = combineReducers({
  posts: postReducer,
});

// Persisted reducer
const persistedReducer = persistReducer(persistConfig, rootReducer);

// Configure store
const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =&amp;gt;
    getDefaultMiddleware({
      serializableCheck: false, // Required for redux-persist
    }),
});

// Persistor for persisting the store
export const persistor = persistStore(store);
export default store;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Wrap with Persisit Gate:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Provider store={store}&amp;gt; 
  &amp;lt;PersistGate loading={null} persistor={persistor}&amp;gt; 
    &amp;lt;App /&amp;gt; 
  &amp;lt;/PersistGate&amp;gt; 
&amp;lt;/Provider&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Optional Enhancements&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use sessionStorage Instead of localStorage:&lt;/strong&gt;&lt;br&gt;
Change the storage to session-based (clears when the browser closes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import storageSession from 'redux-persist/lib/storage/session';
const persistConfig = { key: 'root', storage: storageSession };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Selective Persistence:&lt;/strong&gt;&lt;br&gt;
Only persist specific slices of the state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const persistConfig = {
  key: 'root',
  storage,
  whitelist: ['posts'], // Only persist posts
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have created a simple blog project with react, redux and ant design having CRUD functionality. You can check it out.&lt;br&gt;
&lt;strong&gt;Project Link&lt;/strong&gt; - &lt;a href="https://github.com/Nur-Alam-Limon/Redux-Blog-Project" rel="noopener noreferrer"&gt;Redux Blog App&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎯 Master Redux Toolkit and elevate your React apps!&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
