TypeScript nomlar fazolari (namespaces)
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 enumdan 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
- Har bir nom maydonini modul fayliga aylantiring
exportni ES moduli eksporti bilan almashtiring- ES moduli sintaksisidan foydalanish uchun importlarni yangilang
- Qurilish tizimingizni modullarni boshqarish uchun sozlang
- Yangi modul tuzilishi bilan ishlash uchun testlarni yangilang
- Webpack yoki Rollup kabi paketlardan foydalanishni o‘ylab ko‘ring
"module": "ESNext"ishlatish uchuntsconfig.jsonyangilang
Migratsiya vositalari
ts-migrate- Facebook-dan avtomatik migratsiya vositasi- Nom maydonlarini aniqlash uchun
no-namespaceqoidasi bilantslint - TypeScript-ning o‘rnatilgan refaktoring vositalari
W3Schools Pathfinder
Yutuqlaringizni kuzating – bu bepul!
