How to Work with TypeScript Decorators in Angular

TypeScript decorators are a special kind of declaration that can be attached to a class, method, accessor, property, or parameter. In Angular, decorators provide a way to add metadata to classes, making them highly powerful for creating reusable components, services, and more. This guide explains how to work with TypeScript decorators in Angular, providing examples to help understand their usage better.

What Are TypeScript Decorators?

Decorators are functions that modify the behavior of a class or class member. In Angular, decorators are used to define components, directives, pipes, and injectable services. They provide a declarative way to apply metadata to a class, which Angular uses for various purposes, such as creating instances of components or injecting dependencies.

Common Angular Decorators

Angular has several built-in decorators used for different purposes. Below are the most common Angular decorators:

  • @Component - Defines an Angular component.
  • @Directive - Defines an Angular directive.
  • @Pipe - Defines an Angular pipe.
  • @Injectable - Defines a service that can be injected into other components or services.
  • @Input - Decorates a property to make it a data-binding input.
  • @Output - Decorates a property to make it an event-binding output.

Using @Component Decorator

The @Component decorator is used to define an Angular component. It provides metadata about the component, such as its selector, template, styles, and other configurations.

import { Component } from '@angular/core';

@Component({
  selector: 'app-hello-world',
  template: `<h1>Hello, World!</h1>`,
  styles: ['h1 { color: blue; }']
})
export class HelloWorldComponent { }

In this example, the @Component decorator defines a simple component with a template displaying "Hello, World!". The selector specifies the custom HTML tag to use for this component.

Using @Injectable Decorator

The @Injectable decorator is used to define a service class that can be injected into other components or services. It is an essential part of Angular's dependency injection system.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  getData() {
    return ['Angular', 'TypeScript', 'Decorators'];
  }
}

Here, the @Injectable decorator makes the DataService available for dependency injection throughout the application.

Using @Input and @Output Decorators

The @Input and @Output decorators are used to create input properties and output events in Angular components. They are commonly used for component communication.

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
    <p>{{ message }}</p>
    <button (click)="sendMessage()">Send Message</button>
  `
})
export class ChildComponent {
  @Input() message: string;
  @Output() messageEvent = new EventEmitter();

  sendMessage() {
    this.messageEvent.emit('Hello from Child Component!');
  }
}

In this example, the @Input decorator is used to pass data from a parent component to a child component. The @Output decorator is used to send data from the child component back to the parent component through an event.

Creating Custom Decorators

Custom decorators can be created in Angular to add specific behavior or metadata to classes, methods, or properties. Below is an example of a simple class decorator:

function LogClass(constructor: Function) {
  console.log('Class Decorator called:', constructor);
}

@LogClass
class MyService {
  constructor() {
    console.log('MyService created');
  }
}

Here, the LogClass function is a custom decorator that logs the class to the console when it is defined. Applying @LogClass to MyService logs messages during its creation.

Conclusion

Decorators in Angular provide a powerful way to add metadata and behavior to classes, methods, properties, and parameters. Understanding how to use built-in decorators like @Component, @Injectable, @Input, and @Output is essential for effective Angular development. Additionally, custom decorators can be created to meet specific needs in an application, adding flexibility to the development process.