Decorators
Metaprogramming with decorators for cross-cutting concerns in classes, methods, and properties.
Decorator Stages and Standards
TC39 stage 3 decorators (TypeScript 5.0+ with `experimentalDecorators` disabled) follow a new standard distinct from legacy experimental decorators used by Angular and older NestJS versions. Verify which decorator model your framework targets before adopting patterns.
Decorators are functions applied to class declarations, methods, accessors, fields, or parameters, transforming or wrapping the decorated target at definition time.
- Stage 3 vs legacy experimental decorators
- Check framework compatibility first
- Applied at class definition time
Class and Method Decorators
Class decorators receive the constructor and can replace or extend it — used for registration, dependency injection metadata, and serialization setup. Method decorators wrap the original method, enabling logging, timing, authorization checks, and memoization.
Keep decorator logic thin — heavy work in decorators obscures behavior. Compose small decorators rather than one decorator that does everything.
- Class decorators for registration/DI
- Method decorators wrap behavior
- Compose small focused decorators
function logged(_target: unknown, ctx: ClassMethodDecoratorContext) {
return function (this: unknown, ...args: unknown[]) {
console.log('calling', ctx.name);
};
}Property and Parameter Decorators
Field decorators can customize access or initialization — common in validation frameworks attaching metadata. Parameter decorators mark injection points in DI containers (NestJS `@Inject()` pattern).
Legacy parameter decorators only receive metadata — they cannot replace parameters. Modern frameworks store reflection metadata via `reflect-metadata` for runtime injection resolution.
- Field decorators for metadata/validation
- Parameter decorators mark DI injection
- Often paired with reflect-metadata
Framework Usage Patterns
Angular uses decorators extensively (`@Component`, `@Injectable`). NestJS uses them for controllers, guards, and pipes. Understanding decorator execution order matters when multiple decorators stack on the same target.
Outside these ecosystems, decorators are less common in application code. Prefer explicit middleware, higher-order functions, or composition when not using a decorator-native framework.
- Angular and NestJS are decorator-centric
- Decorator order affects composition
- Prefer functions outside decorator frameworks
Testing and Debugging
Decorators modify classes at load time — bugs may appear before any test runs. Unit test decorated classes in isolation and verify metadata side effects separately from business logic.
Source maps and decorator transpilation can complicate stack traces. Document custom decorators on team wikis so reviewers understand implicit behavior applied at import time.
- Test decorated classes in isolation
- Document custom decorator behavior
- Watch stack trace complexity