WisarWisar
Dasturlash kitobi/7-QISM — TypeScript16 daqiqa

7.6-bob: Decorators (dekoratorlar)

7-QISM — TypeScript · 6-mavzu


1. Kirish va motivatsiya

Turlar tizimini to'liq (7.2-7.5) bildik. Endi TS'ning maxsus, kuchli xususiyatini — decorators (dekoratorlar) — o'rganamiz. Dekorator — class, metod, xususiyat yoki parametrga "yorliq" (annotation) qo'shuvchi maxsus sintaksis (@). Ko'p marta ko'rdik: TypeORM 6.13-bob entity'lari @Entity, @Column bilan; Prisma 6.12-bob emas, lekin NestJS (8) butunlay dekorator asosida (@Controller, @Injectable, @Get). Bu bob — 8-QISM (NestJS) ga bevosita, eng muhim tayyorgarlik.

Dekorator — metaprogramming (kod ustida kod) vositasi. Oddiy holatda funksiya yoki class'ga qo'shimcha xulq qo'shish uchun uni o'rab olardik (wrapper). Dekorator buni deklarativ, toza qiladi: class/metod tepasiga @LogTime yozasiz — va u avtomatik vaqtni o'lchaydi (kodni o'zgartirmasdan). @Controller, @Get("/users"), @Injectable — bularning hammasi dekorator. Ular metama'lumot (metadata) saqlaydi — framework (NestJS) keyin uni o'qib, ishni quradi (routing, dependency injection — 8.2).

Muhim nuans: dekoratorlarning ikki versiyasi bor: legacy (eski, experimentalDecorators — TypeORM/NestJS hozir shuni ishlatadi) va Stage 3 (yangi, TS 5.0+ standart). Bu bob ikkalasini ham tushuntiradi, lekin asosiy e'tibor — legacy (chunki sizning stack'ingiz — TypeORM/NestJS — uni ishlatadi) va reflect-metadata (NestJS DI asosi). Bu bob: dekorator nima, turlari (class/metod/xususiyat/parametr), legacy vs Stage 3, reflect-metadata — chuqur, NestJS'ga tayyorgarlik.

O'xshatish: dekorator — sovg'ani o'rash qog'ozi/lenta. Sovg'a (class/metod) o'z-o'zicha bor; dekorator (@) uni o'raydi — qo'shimcha xususiyat beradi (chiroyli ko'rinish, yorliq), lekin sovg'aning o'zini o'zgartirmaydi. @Injectable — "bu class — xizmat" yorlig'i; @Get("/users") — "bu metod — GET route" yorlig'i. Framework yorliqlarni o'qib, kerakli ishni quradi.

Nega muhim?

  • NestJS (8) asosi — butunlay dekorator (@Controller, @Injectable, @Get).
  • TypeORM (6.13) — entity dekoratorlari (@Entity, @Column).
  • Metaprogramming — toza, deklarativ qo'shimcha xulq.
  • reflect-metadata — NestJS dependency injection 8.2-bob ning yuragi.

2. Nazariya — chuqur tushuntirish

2.1. Dekorator nima va nega

Dekorator@ bilan boshlanadigan, class/a'zoga qo'shiladigan maxsus funksiya (typescriptlang):

ts
@Injectable()                    // class dekoratori
class UserService {
  @Log()                         // metod dekoratori
  topUser(@Param() id: number) {}// parametr dekoratori
}

Dekorator — funksiya: @X — aslida X funksiyasini chaqiradi (class/metod ustida). U metama'lumot qo'shadi yoki xulqni o'zgartiradi. Deklarativ (@) — kodni o'rab olishdan toza. NestJS/TypeORM butun arxitekturasini shunga quradi.

2.2. Metaprogramming (kod ustida kod)

text
  Oddiy: funksiyani o'rab olish (wrapper) — verbose
  function logBilan(fn) { return (...args) => { log(); return fn(...args); }; }
  const f = logBilan(asliy);

  Dekorator: deklarativ (toza)
  @Log
  asliy() {}            // @Log avtomatik o'raydi (kodni o'zgartirmasdan)

Metaprogramming — "kod haqida kod" (kodni kuzatish/o'zgartirish). Dekorator — TS'da metaprogramming vositasi. Wrapper o'rniga deklarativ yorliq. Framework'lar (NestJS) buni metama'lumot saqlash uchun ishlatadi 2.10-bob.

2.3. Dekoratorni yoqish (sozlama)

json
// tsconfig.json — legacy dekoratorlar uchun (TypeORM/NestJS — 2.11)
{
  "compilerOptions": {
    "experimentalDecorators": true,     // legacy dekoratorlar
    "emitDecoratorMetadata": true       // metama'lumot (reflect-metadata — 2.10)
  }
}

Legacy dekorator uchun ikki sozlama: experimentalDecorators: true (dekoratorni yoqadi) + emitDecoratorMetadata: true (tur metama'lumotini chiqaradi — NestJS DI uchun zarur — 2.10). Stage 3 (TS 5.0+ standart) — sozlamasiz ishlaydi, lekin metadata boshqacha. NestJS — hozir legacy 2.11-bob.

2.4. Class dekorator

Class dekorator — class ustida; class'ni kuzatadi/o'zgartiradi (typescriptlang):

ts
// Legacy class dekorator (target — constructor)
function Muhrlangan(constructor: Function) {
  Object.seal(constructor);             // class'ni "muhrlash"
  Object.seal(constructor.prototype);
}

@Muhrlangan
class User {
  constructor(public ism: string) {}
}

// Parametrli dekorator (dekorator factory — 2.8)
function Entity(jadval: string) {
  return function (constructor: Function) {
    // jadval nomini metama'lumotga saqlash (2.10)
  };
}
@Entity("users")                        // TypeORM uslubi (6.13)
class UserEntity {}

Class dekorator — class constructorini oladi. Kuzatish (log), o'zgartirish (muhrlash), yoki metama'lumot saqlash (TypeORM @Entity("users") — jadval nomi). NestJS @Controller, @Injectable, @Module — class dekoratorlar.

2.5. Metod dekorator

ts
// Metod dekorator (target, nom, descriptor)
function Log(target: any, nom: string, descriptor: PropertyDescriptor) {
  const asliy = descriptor.value;       // asl metod
  descriptor.value = function (...args: any[]) {   // o'ralgan
    console.log(`${nom} chaqirildi:`, args);
    const natija = asliy.apply(this, args);
    console.log(`${nom} natija:`, natija);
    return natija;
  };
}

class Kalkulyator {
  @Log
  summa(a: number, b: number): number { return a + b; }   // @Log o'raydi
}

Metod dekorator — metodni o'raydi (descriptor.value orqali): log, timing, kesh, auth tekshiruvi. NestJS @Get("/users"), @UseGuards() — metod dekoratorlar (route, guard — 8.7). Bu — eng ko'p ishlatiladigan dekorator turi.

2.6. Property (xususiyat) dekorator

ts
// Xususiyat dekorator (target, nom)
function Default(qiymat: any) {
  return function (target: any, nom: string) {
    target[nom] = qiymat;               // default qiymat
  };
}

class Config {
  @Default(3000)
  port: number;
}

// TypeORM uslubi (6.13)
class User {
  @Column({ length: 50 })               // xususiyat dekorator
  ism: string;
}

Property dekorator — xususiyatga (target, nom). Descriptor yo'q (ES5'da instance xususiyat tavsifi yo'q). TypeORM @Column, class-validator @IsEmail 5.9-bob, NestJS @Inject — xususiyat dekoratorlar. Metama'lumot saqlash uchun 2.10-bob.

2.7. Parameter dekorator

ts
// Parametr dekorator (target, metodNom, indeks) — faqat legacy
function Param(target: any, metodNom: string, indeks: number) {
  // parametr metama'lumotini saqlash (indeks bo'yicha)
}

class UserController {
  topUser(@Param id: number) {}         // parametr dekorator
}

Parametr dekorator — faqat legacy: Stage 3'da yo'q 2.11-bob. NestJS @Body(), @Param(), @Query(), @Req() 8.5-bob — parametr dekoratorlar (so'rovdan ma'lumot olish). Shuning uchun NestJS legacy dekorator ishlatadi (2.3, 2.11).

2.8. Decorator factory (parametrli dekorator)

ts
// Dekorator factory — parametr qabul qiladi (dekorator QAYTARADI)
function Role(rol: string) {            // factory (parametr)
  return function (target: any, nom: string, descriptor: PropertyDescriptor) {
    // rol metama'lumotini saqlash (RBAC — 5.17, 8.7)
  };
}

class AdminController {
  @Role("admin")                        // parametrli (factory chaqiriladi)
  ochirUser() {}
}

Decorator factory — dekoratorni sozlash uchun (parametr olish): @Role("admin")Role("admin") chaqiriladi, u dekorator qaytaradi. @Entity("users"), @Get("/path"), @Column({...}) — hammasi factory (parametrli). @X (parametrsiz) vs @X(...) (factory).

2.9. Dekorator bajarilish tartibi

ts
function Birinchi() { console.log("Birinchi factory"); return () => console.log("Birinchi"); }
function Ikkinchi() { console.log("Ikkinchi factory"); return () => console.log("Ikkinchi"); }

class Misol {
  @Birinchi()
  @Ikkinchi()
  metod() {}
}
// Tartib: "Birinchi factory", "Ikkinchi factory" (yuqoridan)
//         "Ikkinchi", "Birinchi" (pastdan yuqoriga — bajarilish)

Tartib: factory'lar yuqoridan pastga chaqiriladi; dekoratorlar pastdan yuqoriga bajariladi (matryoshka — ichkaridan tashqariga). Umumiy: parametr metod/xususiyat class (a'zolar, keyin class). Murakkab holatda muhim.

2.10. reflect-metadata (NestJS DI asosi)

reflect-metadata — class/a'zolar haqida metama'lumot saqlash/o'qish kutubxonasi (NestJS DI yuragi):

ts
import "reflect-metadata";             // (TypeORM/NestJS — 6.13: 2.3)

// Metama'lumot saqlash
function Saqla(qiymat: string) {
  return Reflect.metadata("kalit", qiymat);   // metama'lumot
}

@Saqla("user-service")
class UserService {}

// O'qish
const meta = Reflect.getMetadata("kalit", UserService);   // "user-service"

reflect-metadata + emitDecoratorMetadata (2.3) — NestJS dependency injection 8.2-bob ning asosi: TS design:paramtypes metama'lumotini chiqaradi (constructor parametrlari turlari), NestJS uni o'qib, qaysi bog'liqlikni qaysi joyga avtomatik beradi (DI). Bu — "sehrning" ichki ishi (8.2'da chuqur).

2.11. Legacy vs Stage 3 (ikki versiya)

text
  ┌──────────────┬────────────────────┬─────────────────────┐
  │              │ Legacy (eski)      │ Stage 3 (yangi)     │
  ├──────────────┼────────────────────┼─────────────────────┤
  │ Sozlama      │ experimentalDecorators│ standart (TS 5.0+)│
  │ Metadata     │ emitDecoratorMetadata│ boshqacha           │
  │ Parametr dek.│  bor             │  yo'q             │
  │ NestJS/TypeORM│  ishlatadi      │ hali emas           │
  │ Sintaksis    │ (target, nom, desc)│ (value, context)    │
  └──────────────┴────────────────────┴─────────────────────┘

Hozir (2026): NestJS va TypeORM — legacy dekorator ishlatadi (parametr dekorator + reflect-metadata kerak — 2.7, 2.10). Stage 3 — standart, lekin parametr dekorator yo'q (NestJS ishlata olmaydi hozircha). Sizning stack'ingiz uchun — legacy (experimentalDecorators + emitDecoratorMetadata). Kelajakda Stage 3'ga o'tishi mumkin.

2.12. Dekoratorlar qayerda ishlatiladi (real)

text
  NestJS (8):
  @Module, @Controller, @Injectable    — arxitektura (class)
  @Get, @Post, @UseGuards              — route, guard (metod)
  @Body, @Param, @Query                — so'rov ma'lumoti (parametr)

  TypeORM 6.13-bob:
  @Entity, @Column, @PrimaryGeneratedColumn, @OneToMany   — DB model

  class-validator 5.9-bob:
  @IsEmail, @MinLength, @IsNotEmpty    — validatsiya

   Dekorator — zamonaviy backend (NestJS) ning asosiy sintaksisi

2.13. Custom dekorator (amaliy)

ts
// Amaliy: metod vaqtini o'lchash (timing — 5.12)
function VaqtO'lcha(target: any, nom: string, descriptor: PropertyDescriptor) {
  const asliy = descriptor.value;
  descriptor.value = async function (...args: any[]) {
    const boshlandi = Date.now();
    const natija = await asliy.apply(this, args);
    console.log(`${nom}: ${Date.now() - boshlandi}ms`);   // log 5.12-bob
    return natija;
  };
}

class Service {
  @VaqtO'lcha
  async ogirIsh() { /* ... */ }       // avtomatik vaqt o'lchanadi
}

Custom dekoratorlar — log, timing, kesh, retry, auth — qayta ishlatiladigan xulq. Lekin ehtiyot — ortiqcha dekorator kodni "sehrli" (tushunarsiz) qiladi. NestJS'da custom dekorator (8) — keng (masalan @CurrentUser()).

2.14. Dekorator ehtiyotkorliklari

text
   Ehtiyot:
  - Legacy/Stage 3 farqi (sozlama, sintaksis — 2.11)
  - reflect-metadata import qilish (NestJS/TypeORM — 2.10)
  - Ortiqcha custom dekorator — "sehrli", tushunarsiz kod 2.13-bob
  - Parametr dekorator — faqat legacy 2.7-bob
  - Dekorator runtime'da ishlaydi (tur emas — 7.1: 2.4)

Asosiy maslahat: dekoratorni asosan framework (NestJS/TypeORM) bergan holda ishlatasiz (custom kam). Tushunish — qanday ishlashini bilish uchun (sehir emas). Custom dekorator — faqat aniq, qayta ishlatiladigan xulq uchun.

2.15. Best practices (14)

text
   NestJS/TypeORM uchun legacy sozlama (experimentalDecorators + emitDecoratorMetadata — 2.3)
   reflect-metadata import (eng tepada — 2.10, 6.13: 2.3)
   Decorator factory (parametrli — @X(...) — 2.8)
   Custom dekorator — qayta ishlatiladigan, aniq xulq 2.13-bob
   Ortiqcha "sehir"dan qoching (o'qiladigan — 2.14)
   Framework dekoratorlarini tushuning (NestJS/TypeORM — 2.12)
   Dekorator tartibini biling (yuqoridan/pastdan — 2.9)

3. Sintaksis — tez ma'lumotnoma

ts
// Sozlama 2.3-bob: tsconfig — experimentalDecorators + emitDecoratorMetadata
import "reflect-metadata";              // (2.10)

// Turlari (2.4-2.7)
@ClassDek class X {}                                  // class
class Y { @MetodDek metod() {} }                      // metod
class Z { @XususiyatDek maydon: string; }            // xususiyat
class W { metod(@ParamDek p: number) {} }            // parametr (legacy)

// Factory 2.8-bob: @Role("admin") — parametrli
function Role(r: string) { return (target, nom, desc) => {}; }

// reflect-metadata 2.10-bob: Reflect.metadata(k, v) / Reflect.getMetadata(k, target)

4. Batafsil kod namunalari

Misol 1 — Class dekorator (2.4)

ts
// Class dekorator — log (target = constructor — 2.4)
function LogClass(constructor: Function) {
  console.log(`Class yaratildi: ${constructor.name}`);
}

@LogClass
class UserService {
  constructor(public ism: string) {}
}
// "Class yaratildi: UserService" (yuklanishda)

// Parametrli (factory — 2.8) — TypeORM @Entity uslubi
function Entity(jadval: string) {
  return function (constructor: Function) {
    Reflect.defineMetadata("jadval", jadval, constructor);   // metama'lumot (2.10)
  };
}

@Entity("users")
class User {}
console.log(Reflect.getMetadata("jadval", User));   // "users"

Misol 2 — Metod dekorator: log (2.5)

ts
// Metod chaqiruvini log qilish (2.5)
function Log(target: any, nom: string, descriptor: PropertyDescriptor) {
  const asliy = descriptor.value;
  descriptor.value = function (...args: any[]) {
    console.log(`▶ ${nom}(${args.join(", ")})`);
    const natija = asliy.apply(this, args);
    console.log(`◀ ${nom}  ${natija}`);
    return natija;
  };
  return descriptor;
}

class Kalkulyator {
  @Log
  summa(a: number, b: number): number { return a + b; }
  @Log
  kopaytir(a: number, b: number): number { return a * b; }
}
new Kalkulyator().summa(2, 3);   // ▶ summa(2, 3) ... ◀ summa  5

Misol 3 — Metod dekorator: kesh (2.5, 2.13)

ts
// Natijani keshlash (memoization — 5.21 ruhida)
function Kesh(target: any, nom: string, descriptor: PropertyDescriptor) {
  const asliy = descriptor.value;
  const kesh = new Map<string, any>();             // Map (2.9-JS)
  descriptor.value = function (...args: any[]) {
    const kalit = JSON.stringify(args);
    if (kesh.has(kalit)) {
      console.log(`Kesh hit: ${nom}`);
      return kesh.get(kalit);
    }
    const natija = asliy.apply(this, args);
    kesh.set(kalit, natija);
    return natija;
  };
}

class Service {
  @Kesh
  ogirHisob(n: number): number {
    console.log("Hisoblanmoqda...");
    return n * n;
  }
}
const s = new Service();
s.ogirHisob(5);   // "Hisoblanmoqda..." 25
s.ogirHisob(5);   // "Kesh hit" 25 (qayta hisoblamaydi)

Misol 4 — Decorator factory: auth (2.8)

ts
// Rol tekshiruvi (RBAC — 5.17, NestJS @Roles uslubi — 8.7)
function Roles(...ruxsatRollar: string[]) {        // factory (parametr — 2.8)
  return function (target: any, nom: string, descriptor: PropertyDescriptor) {
    const asliy = descriptor.value;
    descriptor.value = function (user: { rol: string }, ...args: any[]) {
      if (!ruxsatRollar.includes(user.rol)) {
        throw new Error("Ruxsat yo'q");            // (5.17)
      }
      return asliy.apply(this, [user, ...args]);
    };
  };
}

class AdminService {
  @Roles("admin", "superadmin")                    // parametrli
  ochirUser(user: { rol: string }, userId: number) {
    return `${userId} o'chirildi`;
  }
}
// new AdminService().ochirUser({ rol: "user" }, 5);   //  "Ruxsat yo'q"

Misol 5 — Xususiyat dekorator: validatsiya (2.6)

ts
import "reflect-metadata";

// Validatsiya metama'lumotini saqlash (class-validator uslubi — 5.9)
function MinLength(min: number) {
  return function (target: any, nom: string) {
    Reflect.defineMetadata(`validate:${nom}`, { min }, target);   // (2.10)
  };
}

class CreateUserDto {
  @MinLength(2)                                    // xususiyat dekorator
  ism: string;
  @MinLength(8)
  parol: string;
}
// Validator metama'lumotni o'qib, tekshiradi (NestJS ValidationPipe — 8.5)

Misol 6 — reflect-metadata va DI (NestJS asosi — 2.10)

ts
import "reflect-metadata";

// Dependency injection asosi (NestJS — 8.2 soddalashtirilgan)
function Injectable(constructor: Function) {
  // class'ni DI konteynerga ro'yxatdan o'tkazish
}

@Injectable
class Database {
  query(sql: string) { return []; }
}

@Injectable
class UserService {
  // emitDecoratorMetadata — constructor parametr turlarini saqlaydi (2.10)
  constructor(private db: Database) {}             // NestJS db'ni AVTOMATIK beradi (DI)
}

// reflect-metadata orqali parametr turlarini o'qish:
const turlar = Reflect.getMetadata("design:paramtypes", UserService);
console.log(turlar);   // [Database] — NestJS shu asosida DI qiladi (8.2)

Misol 7 — Custom dekorator: retry (2.13)

ts
// Xato bo'lsa qayta urinish (retry — 5.22 ruhida)
function Retry(urinish: number) {
  return function (target: any, nom: string, descriptor: PropertyDescriptor) {
    const asliy = descriptor.value;
    descriptor.value = async function (...args: any[]) {
      let oxirgiXato;
      for (let i = 0; i < urinish; i++) {
        try {
          return await asliy.apply(this, args);
        } catch (err) {
          oxirgiXato = err;
          console.log(`Urinish ${i + 1} muvaffaqiyatsiz`);
        }
      }
      throw oxirgiXato;
    };
  };
}

class ApiService {
  @Retry(3)
  async malumotOl() {
    // tashqi API (ba'zan xato — 5.22)
    return await fetch("/api/data").then((r) => r.json());
  }
}

Misol 8 — TypeORM/NestJS dekoratorlar (real — 2.12)

ts
// TypeORM entity 6.13-bob — dekoratorlar bilan
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";

@Entity("users")                                   // class dekorator
export class User {
  @PrimaryGeneratedColumn()                        // xususiyat dekorator
  id: number;

  @Column({ length: 50 })
  ism: string;

  @OneToMany(() => Order, (o) => o.user)
  orders: Order[];
}

// NestJS controller (8) — dekoratorlar bilan
import { Controller, Get, Post, Body, Param, UseGuards } from "@nestjs/common";

@Controller("users")                               // class dekorator
export class UserController {
  constructor(private userService: UserService) {} // DI (reflect-metadata — 2.10)

  @Get(":id")                                      // metod dekorator
  topUser(@Param("id") id: string) {               // parametr dekorator
    return this.userService.topId(+id);
  }

  @Post()
  @UseGuards(AuthGuard)                            // guard (8.7)
  yarat(@Body() dto: CreateUserDto) {
    return this.userService.yarat(dto);
  }
}
// Bu — 8-QISM (NestJS) ning asosiy sintaksisi (dekorator hamma joyda)

5. To'g'ri va noto'g'ri holatlar

1) Sozlamasiz dekorator (legacy)

text
 experimentalDecorators yo'q  dekorator ishlamaydi (2.3)
 tsconfig: experimentalDecorators + emitDecoratorMetadata

2) reflect-metadata import qilmaslik

ts
//  NestJS/TypeORM DI ishlamaydi (2.10)
@Injectable class Service {}

//  eng tepada
import "reflect-metadata";

3) Factory'siz parametrli dekorator

ts
//  @Role("admin") factory bo'lishi kerak (2.8)
function Role(target, nom, desc) {}   // parametr ololmaydi
@Role("admin")   // xato

//  factory
function Role(rol: string) { return (target, nom, desc) => {}; }

4) Ortiqcha custom dekorator (sehir)

text
 har joyga custom dekorator — tushunarsiz "sehir" (2.14)
 framework dekoratorlari; custom — faqat aniq qayta ishlatiladigan

5) Stage 3 da parametr dekorator

text
 Stage 3'da @Param() ishlamaydi (2.7, 2.11)
 NestJS uchun legacy (experimentalDecorators)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — Unable to resolve signature of ... decorator

Sababi: dekorator sintaksisi/turi noto'g'ri, yoki factory kerak 2.8-bob. Yechimi: to'g'ri dekorator turi (class/metod/parametr); parametrli factory.

Xato 2 — Decorators are not valid here / ishlamaydi

Sababi: experimentalDecorators yo'q 2.3-bob. Yechimi: tsconfig'da yoqing.

Xato 3 — NestJS DI Cannot resolve dependencies

Sababi: emitDecoratorMetadata yoki reflect-metadata yo'q 2.10-bob. Yechimi: ikkalasini yoqing/import qiling; @Injectable.

Xato 4 — Parametr dekorator ishlamaydi (Stage 3)

Sababi: Stage 3'da parametr dekorator yo'q (2.7, 2.11). Yechimi: legacy dekorator.

Xato 5 — Metadata undefined

Sababi: reflect-metadata import yoki saqlash yo'q 2.10-bob. Yechimi: import "reflect-metadata"; Reflect.defineMetadata/getMetadata.

Xato 6 — Dekorator noto'g'ri tartibda

Sababi: tartib tushunilmagan 2.9-bob. Yechimi: factory yuqoridan, bajarilish pastdan; tartibni hisobga oling.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • TS class 7.2-bob: dekorator class/a'zoga.
  • reflect-metadata: NestJS DI 8.2-bob.
  • NestJS (8): butunlay dekorator (@Controller/@Injectable/@Get).
  • TypeORM 6.13-bob: entity dekoratorlari.
  • class-validator 5.9-bob: validatsiya dekoratorlari.
  • tsconfig 7.1-bob: experimentalDecorators sozlamasi.
  • OOP (2.5-JS): class, metod.
  • AOP (aspect-oriented): log/kesh/retry — cross-cutting.

8. Eng yaxshi amaliyotlar (best practices)

  • NestJS/TypeORM uchun legacy sozlama (experimentalDecorators + emitDecoratorMetadata — 2.3).
  • reflect-metadata import (eng tepada — 2.10).
  • Decorator factory (parametrli — @X(...) — 2.8).
  • Custom dekorator — aniq, qayta ishlatiladigan xulq (log/kesh/retry — 2.13).
  • Ortiqcha "sehir"dan qoching (o'qiladigan — 2.14).
  • Framework dekoratorlarini tushuning (qanday ishlaydi — sehir emas — 2.12).
  • Dekorator tartibini biling (factory yuqoridan, bajarilish pastdan — 2.9).
  • Legacy vs Stage 3 farqini biling (NestJS — legacy — 2.11).
  • Parametr dekorator — faqat legacy (NestJS @Body/@Param — 2.7).
  • Metama'lumot saqlash (Reflect.defineMetadata — 2.10).

9. Amaliy loyiha: "Custom Dekoratorlar Kutubxonasi"

Dekoratorlarni mustahkamlash (NestJS'ga tayyorgarlik).

Maqsad

Turli xil custom dekoratorlar yaratish: class, metod, xususiyat, factory — va reflect-metadata bilan metama'lumot.

Talablar (requirements)

  1. Sozlama: tsconfig (experimentalDecorators + emitDecoratorMetadata); reflect-metadata (2.3, 2.10).
  2. Class dekorator: log yoki Entity (metama'lumot — Misol 1, 2.4).
  3. Metod dekorator: Log (chaqiruv), Kesh (memoization) — Misol 2, 3, 2.5.
  4. Decorator factory: Roles (auth), Retry (Misol 4, 7, 2.8).
  5. Xususiyat dekorator: validatsiya metama'lumot (MinLength — Misol 5, 2.6).
  6. reflect-metadata: saqlash/o'qish; DI namunasi (Misol 6, 2.10).
  7. VaqtO'lcha: metod timing 2.13-bob.
  8. Tartib: dekorator bajarilish tartibini ko'rsating 2.9-bob.
  9. TypeORM/NestJS namunasi: real dekorator ishlatish (Misol 8, 2.12).
  10. O'qiladigan: ortiqcha sehir yo'q 2.14-bob.

Maslahatlar (hint)

  • tsconfig: experimentalDecorators + emitDecoratorMetadata (2.3, 1-xato).
  • reflect-metadata eng tepada (2.10, 2-xato).
  • Parametrli factory (@X(...) — 2.8, 3-xato).
  • Metod: descriptor.value o'rab 2.5-bob.
  • Metadata: Reflect.defineMetadata/getMetadata 2.10-bob.
  • Kesh: Map (2.9-JS, Misol 3).

"Tayyor" mezonlari (acceptance criteria)

  • Sozlama (experimentalDecorators, reflect-metadata).
  • Class dekorator (log/Entity).
  • Metod dekorator (Log, Kesh).
  • Decorator factory (Roles, Retry).
  • Xususiyat dekorator (validatsiya).
  • reflect-metadata (saqlash/o'qish).
  • Timing dekorator.
  • Tartib ko'rsatilgan.
  • Real namuna (TypeORM/NestJS uslubi).
  • O'qiladigan (sehir yo'q).

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda TS'ning maxsus xususiyatini — decorators — o'rgandik:

  • Dekorator (@ — class/a'zoga yorliq — 2.1); metaprogramming 2.2-bob; sozlama (experimentalDecorators + emitDecoratorMetadata — 2.3).
  • Turlari: class 2.4-bob, metod 2.5-bob, xususiyat 2.6-bob, parametr (legacy — 2.7); decorator factory (parametrli — 2.8); tartib 2.9-bob.
  • reflect-metadata (metama'lumot — NestJS DI asosi — 2.10); legacy vs Stage 3 (NestJS — legacy — 2.11).
  • Real ishlatish (NestJS/TypeORM/class-validator — 2.12); custom (log/kesh/retry — 2.13); ehtiyot 2.14-bob.

Keyingi bob — 7.7-bob: TS bilan Node/Express loyihasi (declaration files, modullar). 7-QISMning yakuniy bobi. TypeScript bilimini amalda — to'liq TS Node/Express backend loyihasi (tuzilma, tsconfig, build, declaration files .d.ts, modullar) — birlashtiramiz. Bu — 7-QISMni yakunlab, 8-QISM (NestJS) ga to'liq tayyorlaydi.


Foydalanilgan rasmiy/ishonchli manbalar

  • typescriptlang.org — Decorators (class, method, property, parameter, factory, order)
  • NestJS docs / Trilon — Metadata deep dive (reflect-metadata, design:paramtypes, DI)
  • Medium/LogRocket — TypeScript decorators 2026 (legacy vs Stage 3)

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
7.6-bob: Decorators (dekoratorlar) — Wisar