🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

टाइपस्क्रिप्ट डिज़ाइन पैटर्न 2026: सिंगलटन, फैक्ट्री, ऑब्जर्वर और रिपोजिटरी

⏱️6 min read  ·  1,146 words

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

सिंगलटन पैटर्न

class DatabasePool {
  private static instance: DatabasePool | null = null;
  private connections: Connection[] = [];

  private constructor(private readonly config: DBConfig) {
    // Private constructor prevents direct instantiation
  }

  static getInstance(config?: DBConfig): DatabasePool {
    if (!DatabasePool.instance) {
      if (!config) throw new Error("Config required for first initialization");
      DatabasePool.instance = new DatabasePool(config);
    }
    return DatabasePool.instance;
  }

  async query<T>(sql: string, params: unknown[]): Promise<T[]> {
    const conn = await this.acquire();
    try {
      return await conn.execute<T>(sql, params);
    } finally {
      this.release(conn);
    }
  }

  private async acquire(): Promise<Connection> {
    // Get available connection from pool
    return this.connections.pop() ?? await createConnection(this.config);
  }

  private release(conn: Connection): void {
    this.connections.push(conn);
  }
}

// Usage
const db = DatabasePool.getInstance({ host: "localhost", port: 5432 });
const users = await db.query<User>("SELECT * FROM users WHERE id = $1", [1]);

बिल्डर पैटर्न

interface QueryConfig {
  table: string;
  conditions: string[];
  columns: string[];
  limit?: number;
  offset?: number;
  orderBy?: { column: string; direction: "ASC" | "DESC" };
}

class QueryBuilder {
  private config: QueryConfig;

  constructor(table: string) {
    this.config = { table, conditions: [], columns: [] };
  }

  select(...columns: string[]): this {
    this.config.columns.push(...columns);
    return this;
  }

  where(condition: string): this {
    this.config.conditions.push(condition);
    return this;
  }

  orderBy(column: string, direction: "ASC" | "DESC" = "ASC"): this {
    this.config.orderBy = { column, direction };
    return this;
  }

  limit(n: number): this {
    this.config.limit = n;
    return this;
  }

  offset(n: number): this {
    this.config.offset = n;
    return this;
  }

  build(): string {
    const cols = this.config.columns.length ? this.config.columns.join(", ") : "*";
    let query = `SELECT ${cols} FROM ${this.config.table}`;
    if (this.config.conditions.length) {
      query += ` WHERE ${this.config.conditions.join(" AND ")}`;
    }
    if (this.config.orderBy) {
      query += ` ORDER BY ${this.config.orderBy.column} ${this.config.orderBy.direction}`;
    }
    if (this.config.limit) query += ` LIMIT ${this.config.limit}`;
    if (this.config.offset) query += ` OFFSET ${this.config.offset}`;
    return query;
  }
}

const query = new QueryBuilder("users")
  .select("id", "name", "email")
  .where("active = true")
  .where("role = 'admin'")
  .orderBy("created_at", "DESC")
  .limit(10)
  .build();

फ़ैक्टरी पैटर्न

interface NotificationSender {
  send(to: string, message: string): Promise<void>;
}

class EmailSender implements NotificationSender {
  async send(to: string, message: string): Promise<void> {
    await sendEmail({ to, subject: "Notification", body: message });
  }
}

class SMSSender implements NotificationSender {
  async send(to: string, message: string): Promise<void> {
    await sendSMS({ to, message: message.slice(0, 160) });
  }
}

class PushSender implements NotificationSender {
  async send(to: string, message: string): Promise<void> {
    await sendPushNotification({ userId: to, body: message });
  }
}

type NotificationType = "email" | "sms" | "push";

function createNotificationSender(type: NotificationType): NotificationSender {
  const senders: Record<NotificationType, () => NotificationSender> = {
    email: () => new EmailSender(),
    sms: () => new SMSSender(),
    push: () => new PushSender(),
  };
  const factory = senders[type];
  if (!factory) throw new Error(`Unknown notification type: ${type}`);
  return factory();
}

// Usage
const sender = createNotificationSender("email");
await sender.send("alice@example.com", "Your order has shipped!");

प्रेक्षक/घटना उत्सर्जक पैटर्न

type EventMap = {
  "user:created": { id: number; email: string };
  "order:placed": { orderId: string; total: number; userId: number };
  "payment:failed": { orderId: string; error: string };
};

type EventHandler<T> = (data: T) => void | Promise<void>;

class TypedEventEmitter<Events extends Record<string, unknown>> {
  private handlers: Partial<{
    [K in keyof Events]: EventHandler<Events[K]>[];
  }> = {};

  on<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): this {
    if (!this.handlers[event]) {
      (this.handlers[event] as EventHandler<Events[K]>[]) = [];
    }
    (this.handlers[event] as EventHandler<Events[K]>[]).push(handler);
    return this;
  }

  off<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): this {
    const handlers = this.handlers[event] as EventHandler<Events[K]>[] | undefined;
    if (handlers) {
      (this.handlers[event] as EventHandler<Events[K]>[]) = handlers.filter(h => h !== handler);
    }
    return this;
  }

  async emit<K extends keyof Events>(event: K, data: Events[K]): Promise<void> {
    const handlers = (this.handlers[event] as EventHandler<Events[K]>[] | undefined) ?? [];
    await Promise.all(handlers.map(h => h(data)));
  }
}

const emitter = new TypedEventEmitter<EventMap>();

emitter.on("user:created", async ({ email }) => {
  await sendWelcomeEmail(email);
});

emitter.on("order:placed", async ({ orderId, userId }) => {
  await sendOrderConfirmation(userId, orderId);
});

// TypeScript enforces correct event data types
await emitter.emit("user:created", { id: 1, email: "alice@example.com" });
// await emitter.emit("user:created", { id: 1 });  // TypeScript error!

रणनीति पैटर्न

interface PaymentStrategy {
  charge(amount: number, currency: string): Promise<PaymentResult>;
  refund(transactionId: string, amount: number): Promise<void>;
}

class StripeStrategy implements PaymentStrategy {
  constructor(private apiKey: string) {}

  async charge(amount: number, currency: string): Promise<PaymentResult> {
    const charge = await stripe.charges.create({ amount, currency });
    return { transactionId: charge.id, status: "success" };
  }

  async refund(transactionId: string, amount: number): Promise<void> {
    await stripe.refunds.create({ charge: transactionId, amount });
  }
}

class PayPalStrategy implements PaymentStrategy {
  async charge(amount: number, currency: string): Promise<PaymentResult> {
    const order = await paypal.orders.create({ amount, currency });
    return { transactionId: order.id, status: "success" };
  }

  async refund(transactionId: string, amount: number): Promise<void> {
    await paypal.captures.refund(transactionId, { amount });
  }
}

class PaymentProcessor {
  constructor(private strategy: PaymentStrategy) {}

  setStrategy(strategy: PaymentStrategy): void {
    this.strategy = strategy;
  }

  async processPayment(amount: number, currency: string): Promise<PaymentResult> {
    return this.strategy.charge(amount, currency);
  }
}

// Switch strategy at runtime
const processor = new PaymentProcessor(new StripeStrategy(process.env.STRIPE_KEY!));
const result = await processor.processPayment(9999, "AUD");

// Switch to PayPal for specific users
processor.setStrategy(new PayPalStrategy());

जेनेरिक के साथ रिपॉजिटरी पैटर्न

interface Repository<T, ID = number> {
  findById(id: ID): Promise<T | null>;
  findAll(options?: FindOptions): Promise<T[]>;
  create(data: Omit<T, "id" | "createdAt" | "updatedAt">): Promise<T>;
  update(id: ID, data: Partial<T>): Promise<T>;
  delete(id: ID): Promise<void>;
  count(where?: Partial<T>): Promise<number>;
}

interface FindOptions {
  limit?: number;
  offset?: number;
  orderBy?: string;
  where?: Record<string, unknown>;
}

// Base implementation
abstract class BaseRepository<T extends { id: number }> implements Repository<T> {
  constructor(
    protected readonly db: Database,
    protected readonly tableName: string
  ) {}

  async findById(id: number): Promise<T | null> {
    const result = await this.db.query<T>(
      `SELECT * FROM ${this.tableName} WHERE id = $1`, [id]
    );
    return result[0] ?? null;
  }

  async create(data: Omit<T, "id" | "createdAt" | "updatedAt">): Promise<T> {
    const keys = Object.keys(data);
    const values = Object.values(data);
    const placeholders = keys.map((_, i) => `$${i + 1}`).join(", ");
    const result = await this.db.query<T>(
      `INSERT INTO ${this.tableName} (${keys.join(", ")}) VALUES (${placeholders}) RETURNING *`,
      values
    );
    return result[0];
  }

  // Other methods...
  async findAll(_opts?: FindOptions): Promise<T[]> { return []; }
  async update(_id: number, _data: Partial<T>): Promise<T> { return {} as T; }
  async delete(_id: number): Promise<void> {}
  async count(_where?: Partial<T>): Promise<number> { return 0; }
}

// Specific implementation
class UserRepository extends BaseRepository<User> {
  constructor(db: Database) { super(db, "users"); }

  async findByEmail(email: string): Promise<User | null> {
    const result = await this.db.query<User>(
      "SELECT * FROM users WHERE email = $1", [email]
    );
    return result[0] ?? null;
  }

  async findActive(): Promise<User[]> {
    return this.db.query<User>("SELECT * FROM users WHERE active = true");
  }
}

2026 में टाइपस्क्रिप्ट डिज़ाइन पैटर्न सटीक रूप से शक्तिशाली हैं क्योंकि टाइप सिस्टम संकलन समय पर सही उपयोग को लागू करता है – उपरोक्त ऑब्जर्वर पैटर्न रनटाइम से पहले गलत ईवेंट डेटा को पकड़ता है, रिपोजिटरी पैटर्न टाइप-सुरक्षित डेटाबेस एक्सेस सुनिश्चित करता है। वास्तविक समस्याओं को हल करने के लिए पैटर्न लागू करें, न कि अपने लिए अति-इंजीनियरिंग के पैटर्न के रूप में।

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা