Dekoratörler, sınıfların, özelliklerin, yöntemlerin veya parametrelerin davranışını ek meta bilgisi veya uygulamanın değiştirilmesi yoluyla değiştirmeye olanak tanıyan özel notasyonlardır.
Genellikle bağımlılıkların enjekte edilmesi, günlüğe kaydetme, doğrulama, önbellekleme veya Angular gibi çerçeveler için meta verilerin tanımlanması amacıyla kullanılır.
Basit bir yöntem dekoratörü örneği:
function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const original = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Call: ${propertyKey}(${JSON.stringify(args)})`); return original.apply(this, args); }; } class Example { @Log doSomething(a: number, b: number) { return a + b; } }
Sakıncalı noktalar:
experimentalDecorators'ın tsconfig'de etkinleştirilmesine bağlıdır.Soru: "Dekoratör parametrelerini, uygulandığı yöntemin türünü güvence altına alacak şekilde türlendirmek mümkün mü?"
Cevap: Çoğu durumda, dekoratörün uygulanması aşamasında türlendirme, meta programlamanın dinamik doğası nedeniyle mümkün değildir. Ancak generics ve ek çalışma zamanı kontrolleri ile doğrulama eklenebilir, ancak TypeScript derleyicisi yapı deklare edilirken garanti vermeyecektir.
Örnek:
function MyDecorator(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<number>) { /* ... */ } // Derleyici, yöntemin number döndürdüğünü garanti etmez
Hikaye
Birçok dekoratör bulunan bir projede uygulama sırasını unutmuşlardı: property-dekoratörleri tüm parametrelerden önce uygulandığı için Inject meta verileri kayboldu ve çalışma zamanında bağımlılıkları çözmek imkansız hale geldi.
Hikaye
Geliştiriciler dekoratörleri sınıf yöntemleri yerine sıradan fonksiyonlara uygulamaya karar verdiler ve derleme hataları ve çalışma zamanı etkisinin olmaması karşısında şaşırdılar. TypeScript spesifikasyonunda dekoratörler sadece sınıflara ve onların üyelerine uygulanır.
Hikaye
TypeScript'in sürüm güncellemelerinden ve deneysel ayarlardan sonra özel DI konteynerindeki tüm dekoratör mekanizması bozuldu: yeni sürümün Reflect-metadata'yı açıkça desteklemesi gerektiği ortaya çıktı, aksi takdirde tüm meta bilgi kayboluyordu.