Chapter 3: एडवांस्ड टाइप्स (Advanced Types)

Chapter 3: एडवांस्ड टाइप्स (Advanced Types)

इस अध्याय में, हम TypeScript के कुछ एडवांस्ड टाइप्स और उनकी उपयोगिता के बारे में जानेंगे। एडवांस्ड टाइप्स को समझना महत्वपूर्ण है, क्योंकि ये हमें TypeScript की पूरी क्षमता का उपयोग करने में मदद करते हैं। हम इण्टरफेसेस (Interfaces), क्लासेस (Classes), और जेनरिक्स (Generics) के बारे में विस्तार से चर्चा करेंगे। ये एडवांस्ड टाइप्स हमें कोड को अधिक संरचित, पुनः उपयोग करने योग्य, और प्रबंधनीय बनाने में सहायता करते हैं।

इण्टरफेसेस (Interfaces)

इण्टरफेसेस TypeScript में एक महत्वपूर्ण फीचर है, जो हमें ऑब्जेक्ट्स की संरचना को परिभाषित करने की अनुमति देता है। इण्टरफेसेस का उपयोग करके, हम ऑब्जेक्ट्स के प्रकारों को स्पष्ट और संगठित तरीके से निर्धारित कर सकते हैं। इस सेक्शन में, हम इण्टरफेसेस के विभिन्न पहलुओं और उनके उपयोग के बारे में जानेंगे।

1. इण्टरफेस क्या है? (What is an Interface?)

इण्टरफेस एक प्रकार की अनुबंध (contract) होती है, जो ऑब्जेक्ट की संरचना को परिभाषित करती है। यह प्रॉपर्टीज और मेथड्स के नाम और उनके प्रकार को निर्दिष्ट करती है।

interface Person {
    name: string;
    age: number;
    isStudent?: boolean; // Optional property
}

2. इण्टरफेस का उपयोग (Using Interfaces)

एक बार इण्टरफेस को परिभाषित करने के बाद, हम उसे ऑब्जेक्ट्स या क्लासेस के लिए प्रकार के रूप में उपयोग कर सकते हैं।

2.1 ऑब्जेक्ट्स के साथ इण्टरफेस (Interfaces with Objects)

इण्टरफेस का उपयोग ऑब्जेक्ट्स की संरचना को सुनिश्चित करने के लिए किया जाता है।

interface Person {
    name: string;
    age: number;
    isStudent?: boolean;
}

let person: Person = {
    name: "Daniel",
    age: 30
};

console.log(person.name); // Daniel
console.log(person.age); // 30

2.2 फंक्शन्स के साथ इण्टरफेस (Interfaces with Functions)

हम फंक्शन्स की संरचना को परिभाषित करने के लिए भी इण्टरफेस का उपयोग कर सकते हैं।

interface Greet {
    (name: string, greeting: string): string;
}

const greet: Greet = (name: string, greeting: string) => {
    return `${greeting}, ${name}!`;
}

console.log(greet("Daniel", "Hello")); // Hello, Daniel!

3. एक्स्टेन्डिंग इण्टरफेसेस (Extending Interfaces)

TypeScript में, हम एक इण्टरफेस को दूसरे इण्टरफेस से एक्स्टेन्ड कर सकते हैं। यह हमें मौजूदा इण्टरफेसेस को पुनः उपयोग करने और नए इण्टरफेसेस बनाने की सुविधा देता है।

interface Person {
    name: string;
    age: number;
}

interface Student extends Person {
    grade: string;
}

let student: Student = {
    name: "Mateo",
    age: 8,
    grade: "3rd"
};

console.log(student.name); // Mateo
console.log(student.age); // 8
console.log(student.grade); // 3rd

4. इण्टरफेसेस के साथ क्लासेस (Interfaces with Classes)

क्लासेस में इण्टरफेसेस का उपयोग करके, हम यह सुनिश्चित कर सकते हैं कि एक क्लास में आवश्यक प्रॉपर्टीज और मेथड्स मौजूद हों।

interface Person {
    name: string;
    age: number;
    greet(): string;
}

class Student implements Person {
    name: string;
    age: number;
    grade: string;

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

    greet(): string {
    	return `Hello, my name is ${this.name} and I am in grade ${this.grade}.`;
    }
}

let student = new Student("Mateo", 8, "3rd");
console.log(student.greet()); // Hello, my name is Mateo and I am in grade 3rd.

क्लासेस (Classes)

क्लासेस TypeScript में एक महत्वपूर्ण फीचर हैं, जो ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (OOP) की अवधारणाओं को लागू करने की अनुमति देते हैं। क्लासेस के माध्यम से हम ऑब्जेक्ट्स के लिए ब्लूप्रिंट बना सकते हैं। इस सेक्शन में, हम TypeScript में क्लासेस को परिभाषित करने और उपयोग करने के विभिन्न पहलुओं को जानेंगे।

1. क्लासेस की मूल संरचना (Basic Structure of Classes)

TypeScript में एक क्लास को class कीवर्ड का उपयोग करके परिभाषित किया जाता है। इसमें प्रॉपर्टीज और मेथड्स हो सकते हैं।

class Person {
    name: string;
    age: number;

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

    greet(): string {
    	return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
    }
}

let person = new Person("Daniel", 30);
console.log(person.greet()); // Hello, my name is Daniel and I am 30 years old.

2. एक्सेस मोडिफायर्स (Access Modifiers)

TypeScript में तीन प्रकार के एक्सेस मोडिफायर्स होते हैं: public, private, और protected, जो क्लास के प्रॉपर्टीज और मेथड्स की पहुंच को नियंत्रित करते हैं।

2.1 public

public प्रॉपर्टीज और मेथड्स को क्लास के बाहर से एक्सेस किया जा सकता है। यह डिफ़ॉल्ट मोडिफायर है।

class Person {
    public name: string;
    public age: number;

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

    public greet(): string {
    	return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
    }
}

let person = new Person("Daniel", 30);
console.log(person.greet()); // Hello, my name is Daniel and I am 30 years old.

2.2 private

private प्रॉपर्टीज और मेथड्स को केवल उसी क्लास के भीतर से एक्सेस किया जा सकता है जिसमें वे परिभाषित हैं।

class Person {
    private name: string;
    private age: number;

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

    public greet(): string {
    	return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
    }
}

let person = new Person("Daniel", 30);
// console.log(person.name); // Error: Property 'name' is private and only accessible within class 'Person'.
console.log(person.greet()); // Hello, my name is Daniel and I am 30 years old.


2.3 protected
protected प्रॉपर्टीज और मेथड्स को क्लास और उसकी सब-क्लासेस के भीतर से एक्सेस किया जा सकता है।
class Person {
    protected name: string;
    protected age: number;

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

class Student extends Person {
    private grade: string;

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

    public introduce(): string {
    	return `Hello, my name is ${this.name}, I am ${this.age} years old and I am in grade ${this.grade}.`;
    }
}

let student = new Student("Mateo", 8, "3rd");
console.log(student.introduce()); // Hello, my name is Mateo, I am 8 years old and I am in grade 3rd.

3. क्लास हेरिटेज (Class Inheritance)

TypeScript में, हम एक क्लास को दूसरी क्लास से एक्स्टेंड कर सकते हैं, जिससे हम मौजूदा क्लास के प्रॉपर्टीज और मेथड्स को पुनः उपयोग कर सकते हैं।

class Person {
    name: string;
    age: number;

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

    greet(): string {
    	return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
    }
}

class Student extends Person {
    grade: string;

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

    introduce(): string {
    	return `Hello, my name is ${this.name}, I am ${this.age} years old and I am in grade ${this.grade}.`;
    }
}

let student = new Student("Mateo", 8, "3rd");
console.log(student.introduce()); // Hello, my name is Mateo, I am 8 years old and I am in grade 3rd.

4. स्टैटिक प्रॉपर्टीज और मेथड्स (Static Properties and Methods)

स्टैटिक प्रॉपर्टीज और मेथड्स को क्लास के इंस्टेंस के बजाय क्लास पर ही लागू किया जाता है।

class MathUtil {
    static PI: number = 3.14;

    static calculateCircumference(diameter: number): number {
    	return this.PI * diameter;
    }
}

console.log(MathUtil.PI); // 3.14
console.log(MathUtil.calculateCircumference(10)); // 31.4

जेनरिक्स (Generics)

जेनरिक्स TypeScript का एक शक्तिशाली फीचर है, जो कोड को अधिक लचीला और पुनः उपयोग करने योग्य बनाने में मदद करता है। जेनरिक्स का उपयोग करके हम ऐसे फंक्शन्स, क्लासेस, और इंटरफेसेस बना सकते हैं, जो विभिन्न प्रकारों के साथ काम कर सकते हैं। इस सेक्शन में, हम जेनरिक्स के विभिन्न पहलुओं और उनके उपयोग के बारे में जानेंगे।

1. जेनरिक्स का परिचय (Introduction to Generics)

जेनरिक्स का उपयोग तब किया जाता है जब हमें किसी फंक्शन, क्लास, या इंटरफेस को विभिन्न प्रकारों के साथ काम करने की आवश्यकता होती है। जेनरिक्स हमें टाइप्स को पैरामीटर के रूप में पास करने की अनुमति देता है।

function identity<T>(arg: T): T {
    return arg;
}

let output1 = identity<string>("Hello, TypeScript!");
let output2 = identity<number>(100);

console.log(output1); // Hello, TypeScript!
console.log(output2); // 100

2. जेनरिक्स के साथ फंक्शन्स (Generics with Functions)

जेनरिक्स का सबसे सामान्य उपयोग फंक्शन्स के साथ किया जाता है, जिससे फंक्शन्स विभिन्न प्रकारों के साथ काम कर सकते हैं।

2.1 सिम्पल जेनरिक फंक्शन (Simple Generic Function)

function echo<T>(value: T): T {
    return value;
}

console.log(echo<string>("TypeScript")); // TypeScript
console.log(echo<number>(123)); // 123

2.2 जेनरिक फंक्शन में मल्टीपल टाइप पैरामीटर्स (Multiple Type Parameters in Generic Function)

function merge<T, U>(obj1: T, obj2: U): T & U {
    return { ...obj1, ...obj2 };
}

let mergedObject = merge({ name: "Daniel" }, { age: 30 });
console.log(mergedObject); // { name: "Daniel", age: 30 }

3. जेनरिक्स के साथ क्लासेस (Generics with Classes)

जेनरिक्स का उपयोग क्लासेस के साथ भी किया जा सकता है, जिससे क्लास विभिन्न प्रकारों के साथ काम कर सकती है।

class Box<T> {
    contents: T;

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

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

let stringBox = new Box<string>("Hello");
let numberBox = new Box<number>(123);

console.log(stringBox.getContents()); // Hello
console.log(numberBox.getContents()); // 123

4. जेनरिक्स के साथ इंटरफेसेस (Generics with Interfaces)

जेनरिक्स का उपयोग इंटरफेसेस के साथ भी किया जा सकता है, जिससे इंटरफेस विभिन्न प्रकारों के साथ काम कर सकता है।

interface Pair<T, U> {
    key: T;
    value: U;
}

let stringNumberPair: Pair<string, number> = { key: "Age", value: 30 };
let numberBooleanPair: Pair<number, boolean> = { key: 1, value: true };

console.log(stringNumberPair); // { key: "Age", value: 30 }
console.log(numberBooleanPair); // { key: 1, value: true }

5. जेनरिक्स के साथ कन्स्ट्रेनट्स (Constraints with Generics)

कभी-कभी हमें यह सुनिश्चित करने की आवश्यकता होती है कि जेनरिक टाइप किसी विशेष प्रकार या संरचना का पालन करता है। इसके लिए हम कन्स्ट्रेनट्स का उपयोग कर सकते हैं।

interface HasLength {
    length: number;
}

function logLength<T extends HasLength>(arg: T): void {
    console.log(arg.length);
}

logLength("Hello"); // 5
logLength([1, 2, 3, 4]); // 4
// logLength(123); // Error: Argument of type 'number' is not assignable to parameter of type 'HasLength'.



Table of Contents

Index