Decorators are special annotations that allow modifying the behavior of classes, properties, methods, or parameters through additional metadata or by overriding implementations.
They are usually used for dependency injection, logging, validation, caching, or declaring metadata for frameworks like Angular.
Example of a simple method decorator:
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; } }
Pitfalls:
experimentalDecorators is enabled in tsconfig.Question: "Is it possible to type the decorator parameters in such a way as to guarantee the type of the method to which it is applied?"
Answer: In most cases, typing is not possible at the time of applying the decorator due to the dynamic nature of metaprogramming. However, through generics and additional runtime checks, validation can be added, but the TypeScript compiler does not provide guarantees at the declaration stage of the structure.
Example:
function MyDecorator(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<number>) { /* ... */ } // The compiler does not guarantee that the method returns a number
Story
In a project with a large number of decorators on services, the order of application was neglected: property decorators were applied before all parameters, which led to the loss of Inject metadata and the inability to resolve dependencies at runtime.
Story
Developers decided to apply decorators to regular functions instead of class methods and were surprised by compilation errors and lack of runtime effect. In the TypeScript specification, decorators are applied only to classes and their members.
Story
After updating TypeScript versions and experimental settings, the entire decorator mechanism in the custom DI container broke: it turned out that the new version requires explicit support for Reflect-metadata, otherwise all metadata was lost.