Power of Decorators in TypeScript and NestJS: Adding Metadata and Modifying Behavior

Kyiv Tech Kat
3 min readJul 4, 2023

In the context of TypeScript and NestJS, a decorator is a special kind of declaration that can be attached to a class declaration, method, property, or parameter to provide additional metadata or modify the behavior of the target.

Designed with Canva

What’s a Decorator? 🤔

Decorators are indicated by the @ symbol followed by the decorator name, placed immediately before the declaration they are decorating. They are functions that are executed at runtime with access to the target declaration and can perform various actions or modifications.

Here are a few key points about decorators:

  1. Metadata: Decorators can be used to add metadata or annotations to a class, method, property, or parameter. This metadata can be used by other parts of the application or libraries to provide additional functionality or perform certain operations based on the metadata.
  2. Syntax: Decorators are applied using a concise syntax that allows them to be placed directly above the declaration they are decorating. For example, @Component() is a decorator applied to a class, @Get() is a decorator applied to a method, and @Inject() is a decorator applied to a parameter.
  3. Execution: Decorators are executed when the target declaration is evaluated at runtime. This allows them to perform actions, modify behavior, or register the target with certain systems or frameworks. The execution order of decorators is from bottom to top for class decorators and from inside to outside for method and property decorators.
  4. Decorator Factories: Decorators can also be created using decorator factories. Decorator factories are higher-order functions that return the actual decorator function. This allows for parameterized decorators that can accept arguments and configure the behavior of the decorator.

Decorators in Action 🎬

Let’s take a glance at how decorators can be employed in a NestJS application:

  • Class Decorators (@Module()):These decorators give life to modules, defining the landscape of features like controllers and services.
  • Method Decorators (@Get(), @Post()): They map your routes to the controller methods, paving the path for HTTP requests to find their way.
  • Parameter Decorators (@Body(), @Param()): Ever precise, these decorators extract data from requests, ensuring your methods get exactly what they need.
  • Custom Decorators: Need something tailor-fit? Custom decorators let you define your own metadata and rules, giving you the creative freedom to innovate.

A NestJS Decorator Example:

Imagine you’re crafting an API endpoint. You want to fetch some user data:

@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}

@Get(':id')
async findOne(@Param('id') id: string): Promise<User> {
return this.usersService.findOne(id);
}
}

In this snippet, @Controller() decorates the class, @Get() decorates the method, and @Param() decorates the parameter. Each decorator plays a pivotal role in making the findOne method accessible and functional.

Wrap Up and Coffee Chat ☕

Decorators in TypeScript and NestJS are the gateway to efficient, organized, and streamlined code. They’re not just syntax; they’re the architects of your application’s functionality. Embrace decorators, and watch your codebase evolve into a well-oiled machine.

Thank you for reading! 🙏 Do follow, clap 👏, and write comments with feedback, questions, and suggestions.

Feeling the article vibe? 🎉 Want to contribute your support or share a coffee with the author? ☕ Head over to Buy Me a Coffee to fuel both charity causes and the dream of ethical tech! 🌟

--

--

Kyiv Tech Kat

Full-stack dev Kateryna from Zaporizhzhia, now in Kyiv. Explore tech with me at kyiv-tech-kat.medium.com. Co-founder of Umbrella UA. Support & ignite change.