Declaration merging — interface avtomatik birlashtirish

~10 daq · TypeScript · Interface

Express bilan ishlayapsiz. Har bir so'rovda req.user bo'lishi kerak — login bo'lgan foydalanuvchi ma'lumotlari. Lekin Express ning Request turida user xususiyati yo'q:

app.get("/profil", (req, res) => {
  console.log(req.user.ism);
  // ❌ Property 'user' does not exist on type 'Request'
});

Express ning manba kodini o'zgartirish mumkin emas. Lekin declaration merging bilan uning turini kengaytirish mumkin.


Declaration merging nima?

Interface bir xil nomda ikki marta e'lon qilinsa — TypeScript ularni avtomatik birlashtiradi. Bu qayta yozish emas — to'ldirish:

interface Foydalanuvchi { ism: string; }
interface Foydalanuvchi { yosh: number; }

// TypeScript ikkalasini birlashtiradi:
// interface Foydalanuvchi {
//   ism:  string;
//   yosh: number;
// }

const user: Foydalanuvchi = { ism: "Jasur", yosh: 25 }; // ✅

Kutubxona turlarini kengaytirish

Express Request turiga user qo'shish:

// src/types/express.d.ts
declare global {
  namespace Express {
    interface Request {
      user?: {
        id:    number;
        ism:   string;
        email: string;
      };
    }
  }
}

Endi barcha route larda req.user TypeScript tomonidan taniladi:

app.get("/profil", (req, res) => {
  if (req.user) {
    res.json({ ism: req.user.ism }); // ✅ — TypeScript biladi
  }
});

Window ga xususiyat qo'shish

Brauzer window ob'ektiga global o'zgaruvchi qo'shish:

// src/types/global.d.ts
declare global {
  interface Window {
    analyticsId: string;
    gtag?: (...args: unknown[]) => void;
  }
}

// Istalgan joyda
window.analyticsId = "UA-12345";
window.gtag?.("event", "click");

Modul augmentation — modulni kengaytirish

Uchinchi tomon kutubxonasining turini kengaytirish:

// src/types/some-lib.d.ts
import "some-lib";

declare module "some-lib" {
  interface SomeLibConfig {
    customOption?: boolean; // yangi xususiyat qo'shildi
  }
}

Muhim: faqat interface da ishlaydi

// ✅ — interface: birlashadi
interface A { x: string; }
interface A { y: number; }
// Natija: { x: string; y: number; }

// ❌ — type: xato
type B = { x: string; };
type B = { y: number; }; // Duplicate identifier 'B'

Tez-tez uchraydigan xatolar

Bir modulda bir xil interfaceni ikki marta tahrirlash:

// ❌ — bir fayl ichida chalkash ko'rinadi
interface Sozlamalar { til: string; }
// ... 200 qator kod ...
interface Sozlamalar { mavzu: string; }

Bu ishlaydi — lekin bir fayl ichida bir interfaceni ikki joyda yozish kodni o'qishni qiyinlashtiradi. Bitta joyda saqlang.

declare global ni eksport qilishni unutish:

// ❌ — bu fayl modul emas, global scope — declare global kerak emas va ishlashi kafolatlanmaydi
interface Window { myProp: string; }

// ✅ — fayl modul bo'lishi uchun biror narsa eksport qiling
export {};
declare global {
  interface Window { myProp: string; }
}

Xulosa

Declaration merging — bir xil nomli interfacelarni TypeScript avtomatik birlashtiradi.

// Amaliy ishlatish:
declare global {
  interface Window   { myProp: string; }     // window kengaytirish
  interface Request  { user?: UserType; }    // express kengaytirish
}

declare module "kutubxona" {
  interface Config { yangi?: boolean; }      // modul kengaytirish
}

Kutubxona turlarini o'zgartirmasdan kengaytirish — declaration merging ning asosiy maqsadi.


Keyingi dars

22-dars: Funksiya parametr va qaytish turlari