TypeScript nomlar fazolari (namespaces)


ULASHISH

TypeScript nom maydonlarini tushunish

TypeScript nom maydonlari (ilgari "ichki modullar" sifatida tanilgan) tegishli funksiyalar uchun konteyner yaratish orqali kodni tartibga solish va nomlash ziddiyatlarini oldini olishning kuchli usulini ta’minlaydi.

Ular katta kod bazalarini tuzishda va ko‘lamni toza, saqlanishi mumkin bo‘lgan tarzda boshqarishda yordam beradi.


Asosiy tushunchalar

  • Logical Grouping : Tegishli kodni nomli konteynerlarga joylashtiring
  • Scope Management : Kod elementlarining ko‘rinishini boshqaring
  • Name Collision Prevention : Xuddi shunday nomlangan komponentlar o‘rtasidagi ziddiyatlardan saqlaning
  • Code Organization : Katta ilovalarni ierarxik tarzda tuzing

Nom maydonlaridan qachon foydalanish kerak

  • Katta eski ilovalarda kodni tashkil qilish
  • Global kutubxonalar bilan ishlash
  • Eski JavaScript kod bazalaridan ko‘chirishda
  • Global miqyosda mavjud bo‘lishi kerak bo‘lgan kod bilan ishlashda

Eslatma: Nom maydonlari hali ham TypeScript-da to‘liq qo‘llab-quvvatlansa-da, zamonaviy ilovalar odatda modullilikni yaxshilash va daraxt silkitishni qo‘llab-quvvatlash uchun ES modullaridan (import/eksport) foydalanadi.

Biroq, nomlar bo‘shliqlarini tushunish eski kod bazalarini va kutubxonani rivojlantirishning ba’zi stsenariylarini saqlash uchun qimmatlidir.


Asosiy nomlar maydoni sintaksisi

Nom maydonlarini yaratish va ulardan foydalanish

Nom maydoni namespace kalit so‘zi yordamida aniqlanadi:

Misol

namespace Validation {
  // Everything inside this block belongs to the Validation namespace

  // Export things you want to make available outside the namespace
  export interface StringValidator {
    isValid(s: string): boolean;
  }

  // This is private to the namespace (not exported)
  const lettersRegexp = /^[A-Za-z]+$/;

  // Exported class - available outside the namespace
  export class LettersValidator implements StringValidator {
    isValid(s: string): boolean {
      return lettersRegexp.test(s);
    }
  }

  // Another exported class
  export class ZipCodeValidator implements StringValidator {
    isValid(s: string): boolean {
      return /^[0-9]+$/.test(s) && s.length === 5;
    }
  }
}

// Using the namespace members
let letterValidator = new Validation.LettersValidator();
let zipCodeValidator = new Validation.ZipCodeValidator();

console.log(letterValidator.isValid("Hello")); // true
console.log(letterValidator.isValid("Hello123")); // false

console.log(zipCodeValidator.isValid("12345")); // true
console.log(zipCodeValidator.isValid("1234")); // false - wrong length
O‘zingiz sinab ko‘ring »


Kengaytirilgan nomlar maydoni xususiyatlari

Ichki nomlar bo‘shliqlari

Ierarxik tashkilot yaratish uchun nomlar maydonlarini joylashtirish mumkin:

Misol

namespace App {
  export namespace Utils {
    export function log(msg: string): void {
      console.log(`[LOG]: ${msg}`);
    }

    export function error(msg: string): void {
      console.error(`[ERROR]: ${msg}`);
    }
  }

  export namespace Models {
    export interface User {
      id: number;
      name: string;
      email: string;
    }

    export class UserService {
      getUser(id: number): User {
        return { id, name: "John Doe", email: "john@example.com" };
      }
    }
  }
}

// Using nested namespaces
App.Utils.log("Application starting");

const userService = new App.Models.UserService();
const user = userService.getUser(1);

App.Utils.log(`User loaded: ${user.name}`);

// This would be a type error in TypeScript
// App.log("directly accessing log"); // Error - log is not a direct member of App
O‘zingiz sinab ko‘ring »

Nom maydoni taxalluslari

Uzoq nomlarni yanada qulayroq qilish uchun nomlar bo‘shliqlari yoki ularning a’zolari uchun taxalluslar yaratishingiz mumkin:

Misol

namespace VeryLongNamespace {
  export namespace DeeplyNested {
    export namespace Components {
      export class Button {
        display(): void {
          console.log("Button displayed");
        }
      }
      export class TextField {
        display(): void {
          console.log("TextField displayed");
        }
      }
    }
  }
}

// Without alias - very verbose
const button1 = new VeryLongNamespace.DeeplyNested.Components.Button();
button1.display();

// With namespace alias
import Components = VeryLongNamespace.DeeplyNested.Components;
const button2 = new Components.Button();
button2.display();

// With specific member alias
import Button = VeryLongNamespace.DeeplyNested.Components.Button;
const button3 = new Button();
button3.display();
O‘zingiz sinab ko‘ring »

Ko‘p faylli nom maydonlari bilan ishlash

Fayllar bo‘yicha nomlar bo‘shliqlarini ajratish

Katta ilovalar ko‘pincha kodni bir nechta fayllarga ajratishni talab qiladi.

TypeScript nom maydonlari fayllar bo‘yicha bo‘linishi va kompilyatsiya vaqtida mos yozuvlar sharhlari yordamida birlashtirilishi mumkin:

Ma’lumot sharhlaridan foydalanish

Ma’lumot sharhlari TypeScript ga fayllar orasidagi munosabatni tushunishga yordam beradi:

validators.ts fayl:

Misol

namespace Validation {
  export interface StringValidator {
    isValid(s: string): boolean;
  }
}

letters-validator.ts fayli (tasdiqlash nom maydonini kengaytiradi):

Misol

/// <reference path="validators.ts" />
namespace Validation {
  const lettersRegexp = /^[A-Za-z]+$/;

  export class LettersValidator implements StringValidator {
    isValid(s: string): boolean {
      return lettersRegexp.test(s);
    }
  }
}

zipcode-validator.ts fayl:

Misol

/// <reference path="validators.ts" />
namespace Validation {
  const zipCodeRegexp = /^[0-9]+$/;

  export class ZipCodeValidator implements StringValidator {
    isValid(s: string): boolean {
      return zipCodeRegexp.test(s) && s.length === 5;
    }
  }
}

main.ts fayl:

Misol

/// <reference path="validators.ts" />
/// <reference path="letters-validator.ts" />
/// <reference path="zipcode-validator.ts" />

// Now you can use the validators from multiple files
let validators: { [s: string]: Validation.StringValidator } = {};
validators["letters"] = new Validation.LettersValidator();
validators["zipcode"] = new Validation.ZipCodeValidator();

// Some samples to validate
let strings = ["Hello", "98052", "101"];

// Validate each
strings.forEach(s => {
  for (let name in validators) {
    console.log(`"${s}" - ${validators[name].isValid(s) ? "matches" : "does not match"} ${name}`);
  }
});

Ushbu fayllarni bitta JavaScript fayliga kompilyatsiya qilish uchun quyidagilardan foydalaning:

Misol

tsc --outFile sample.js main.ts

Nom maydonlari va modullar

Asosiy farqlar

Modullarga nisbatan nom maydonlaridan qachon foydalanishni tushunish TypeScript-ni ishlab chiqish uchun juda muhimdir:

  • Modules zamonaviy TypeScript ilovalarida kodni tartibga solishning afzal usuli hisoblanadi
  • Namespaces hali ham deklaratsiyani birlashtirish yoki eski kod bilan ishlash kabi muayyan stsenariylar uchun foydalidir
  • Modules asboblarni qo‘llab-quvvatlash va daraxtlarni silkitish qobiliyatiga ega
  • Namespaces global kutubxonalarni yaratish uchun foydali bo‘lishi mumkin

ES modullari bilan nomlar bo‘shliqlarini qachon ishlatishni taqqoslash:

Taqqoslash jadvali

Xususiyat Nom maydonlari ES Modules (import/export)
Tavsiya etilgan qamrov/shkala Oddiyroq sozlashlar, kichik ilovalar, eski kod bazalari Har qanday o‘lchamdagi zamonaviy ilovalar; yangi loyihalar uchun afzallik beriladi
Sintaksis va foydalanish Global access via dot notation (e.g., MyNS.Member) Fayl yo‘llari bilan aniq import / export
Yuklash/to‘plash Yuklagich kerak emas; --outFile orqali bitta faylni chiqarishi mumkin Odatda bundler/loader ishlatiladi (Vite, webpack va h.k.)
Fayllar bo‘ylab bo‘linish /// <reference /> sharhlar orqali mumkin Tabiiy; har bir fayl aniq eksport/importga ega moduldir
Daraxt silkitish Cheklangan; Bundlerlar uchun foydalanilmagan kodni yo‘q qilish qiyinroq Zo‘r; o‘lik kodni yo‘q qilish uchun mo‘ljallangan
Global qamrov Encourages globals (namespaced) Globallikdan qochadi; aniq bog‘liqliklar
Kattalashtirish/birlashtirish Deklaratsiyani birlashtirish orqali kuchli qo‘llab-quvvatlash Modulni kengaytirish mumkin, lekin ko‘proq cheklangan
Asboblar va ekotizim Ishlaydi, lekin zamonaviy asboblar bilan kamroq mos keladi Zamonaviy asboblar va platformalarda eng yaxshi yordam
uchun eng yaxshi ishlatiladi Eski kutubxonalar, global skriptlar, muhit turlari Barcha yangi ishlanmalar, kutubxonalar va ilovalar

Kengaytirilgan nomlar maydoni naqshlari

Misol

// Original namespace
declare namespace Express {
  interface Request {
    user?: { id: number; name: string };
  }
  interface Response {
    json(data: any): void;
  }
}

// Later in your application (e.g., in a .d.ts file)
declare namespace Express {
  // Augment the Request interface
  interface Request {
    // Add custom properties
    requestTime?: number;
    // Add methods
    log(message: string): void;
  }

  // Add new types
  interface UserSession {
    userId: number;
    expires: Date;
  }
}

// Usage in your application
const app = express();

app.use((req: Express.Request, res: Express.Response, next) => {
  // Augmented properties and methods are available
  req.requestTime = Date.now();
  req.log('Request started');
  next();
});

Generics bilan nom maydonlari

Misol

// Generic namespace example
namespace DataStorage {
  export interface Repository<T> {
    getAll(): T[];
    getById(id: number): T | undefined;
    add(item: T): void;
    update(id: number, item: T): boolean;
    delete(id: number): boolean;
  }

  // Concrete implementation
  export class InMemoryRepository<T> implements Repository<T> {
    private items: T[] = [];

    getAll(): T[] {
      return [...this.items];
    }

    getById(id: number): T | undefined {
      return this.items[id];
    }

    add(item: T): void {
      this.items.push(item);
    }

    update(id: number, item: T): boolean {
      if (id >= 0 && id < this.items.length) {
        this.items[id] = item;
        return true;
      }
      return false;
    }

    delete(id: number): boolean {
      if (id >= 0 && id < this.items.length) {
        this.items.splice(id, 1);
        return true;
      }
      return false;
    }
  }
}

// Usage
interface User {
  id: number;
  name: string;
  email: string;
}

const userRepo = new DataStorage.InMemoryRepository<User>();
userRepo.add({ id: 1, name: 'John Doe', email: 'john@example.com' });
const allUsers = userRepo.getAll();

Eng yaxshi amaliyotlar

Nomlar maydonining eng yaxshi amaliyotlari

Qilish:

  • Ma’noli, ierarxik nom maydoni nomlaridan foydalaning
  • Nom maydonlaridan faqat kerakli narsalarni eksport qiling
  • Ko‘p faylli nom maydonlarida tartiblash uchun /// <reference /> dan foydalaning
  • Yangi loyihalar uchun modullardan foydalanishni ko‘rib chiqing
  • Yaxshiroq ishlash uchun nomlar maydoni ichida const enumlaridan foydalaning
  • Nom maydonlaringizni JSDoc izohlari bilan hujjatlang

Qilmang:

  • Haddan tashqari chuqur namespace ierarxiyalarini yaratish (2-3 darajadan ortiq)
  • Global miqyosni keraksiz ravishda ifloslantiring
  • Nom maydonlari va modullarni aniq strategiyasiz bir xil loyihada aralashtiring
  • Kichik ilovalar uchun nom maydonlaridan foydalaning - modullarni afzal ko‘ring

Ishlash bo‘yicha mulohazalar

  • Katta nom maydonlari bundle hajmini oshirishi mumkin
  • Katta ilovalar uchun kodni ajratishni ko‘rib chiqing
  • Murakkab nomlar maydoni tuzilmalarida aylana bog‘liqliklariga e’tibor bering
  • Doimiy qiymatlar bilan yaxshiroq ishlash uchun const enum dan foydalaning

Nom maydonlaridan modullarga o‘tish

Misol

// Before: Using namespaces
namespace MyApp {
  export namespace Services {
    export class UserService {
      getUser(id: number) { /* ... */ }
    }
  }
}

// After: Using ES modules
// services/UserService.ts
export class UserService {
  getUser(id: number) { /* ... */ }
}

// app.ts
import { UserService } from './services/UserService';
const userService = new UserService();

Migratsiya bosqichlari

  1. Har bir nom maydonini modul fayliga aylantiring
  2. export ni ES moduli eksporti bilan almashtiring
  3. ES moduli sintaksisidan foydalanish uchun importlarni yangilang
  4. Qurilish tizimingizni modullarni boshqarish uchun sozlang
  5. Yangi modul tuzilishi bilan ishlash uchun testlarni yangilang
  6. Webpack yoki Rollup kabi paketlardan foydalanishni o‘ylab ko‘ring
  7. "module": "ESNext" ishlatish uchun tsconfig.json yangilang

Migratsiya vositalari

  • ts-migrate - Facebook-dan avtomatik migratsiya vositasi
  • Nom maydonlarini aniqlash uchun no-namespace qoidasi bilan tslint
  • TypeScript-ning o‘rnatilgan refaktoring vositalari



W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!