Class dekorator — sinfni o'zgartirish va kengaytirish
NestJS da @Injectable() — classni DI konteyneriga ro'yxatdan o'tkazadi. @Controller("/users") — HTTP yo'lini belgilaydi. Bular — class dekoratorlar. Qanday ishlashini tushunish uchun o'zimiz yozamiz.
Class dekorator imzosi
type ClassDecorator = (target: Function) => void | Function;
target — classning o'zi (constructor funksiyasi).
Metadata qo'shish
function Versiya(n: string) {
return function(target: Function) {
(target as any).versiya = n; // class ga static xususiyat qo'shamiz
};
}
@Versiya("1.0.0")
class API {}
(API as any).versiya; // "1.0.0"
Ro'yxatga olish
const xizmatRo_yxati: Map<string, Function> = new Map();
function Xizmat(nom: string) {
return function(target: Function) {
xizmatRo_yxati.set(nom, target);
console.log(`Ro'yxatga qo'shildi: ${nom}`);
};
}
@Xizmat("foydalanuvchi")
class FoydalanuvchiXizmat {}
@Xizmat("mahsulot")
class MahsulotXizmat {}
xizmatRo_yxati.get("foydalanuvchi"); // FoydalanuvchiXizmat class
Classni kengaytirish
Dekorator yangi class qaytarsa — asl classni almashtiradi:
function Kuzatuvchi<T extends { new(...args: any[]): {} }>(Base: T) {
return class extends Base {
yaratilganVaqt = new Date();
constructor(...args: any[]) {
super(...args);
console.log(`${Base.name} instansi yaratildi`);
}
};
}
@Kuzatuvchi
class Foydalanuvchi {
constructor(public ism: string) {}
}
const u = new Foydalanuvchi("Jasur");
// "Foydalanuvchi instansi yaratildi"
(u as any).yaratilganVaqt; // Date
NestJS @Controller misoli (sodda)
const routelar: Map<Function, string> = new Map();
function Controller(prefiks: string) {
return function(target: Function) {
routelar.set(target, prefiks);
};
}
@Controller("/users")
class UsersController {}
routelar.get(UsersController); // "/users"
Tez-tez uchraydigan xatolar
Dekoratorni yoqmasdan ishlatish:
@MyDecorator
class A {} // ❌ — experimentalDecorators: true bo'lmasa xato
Target turini noto'g'ri aniqlash:
function Deko(target: any) { // any — xavfsiz emas, lekin amalda ko'p ishlatiladi
target.prototype.yangi = true;
}
Xulosa
// Parametrsiz
function Deko(target: Function): void { ... }
@Deko class A {}
// Parametrli (factory)
function Deko(param: string) {
return (target: Function): void => { ... };
}
@Deko("param") class A {}
// Class qaytarish — kengaytirish
function Deko<T extends new(...a: any[]) => {}>(Base: T) {
return class extends Base { yangi = true; };
}
@Deko class A {}
Keyingi dars
55-dars: Method dekorator — metodlarni wrapping qilish