Decorators—Add Metadata and Behavior to Classes

Use decorators to attach metadata and inject reusable behavior into classes, methods, and properties in a clean, declarative way. Learn both the modern ECMAScript standard and the legacy patterns required by popular frameworks.

As developers, we often need to inject behavior, annotate structure, or enforce contracts without polluting our core logic. Think of logging, validation, dependency injection, or marking fields as required. These are cross-cutting concerns. They crop up everywhere—classes, methods, properties—repeating the same logic.

Enter decorators.

Decorators in TypeScript provide a powerful syntax to extend and annotate code behavior at runtime—while keeping business logic crisp and uncluttered. If you’ve worked with Angular or NestJS, you’ve already seen them: @Component(), @Injectable(), @Get(), and more.

TypeScript is currently in a transitional period. For years, developers relied on an experimental version of decorators (Stage 2). Today, TypeScript fully supports the official, standardized JavaScript decorator specification (Stage 3). To be an adaptable developer, you need to understand both systems and how they handle classes, methods, and properties.

The landscape: modern vs. legacy decorators

Before writing code, it is critical to understand the two flavors of decorators coexisting in the TypeScript ecosystem: