Decoradores no TypeScript
Este artigo explica os decoradores no TypeScript.
YouTube Video
Decoradores no TypeScript
Os decoradores no TypeScript são um mecanismo para adicionar funcionalidades ou comportamentos adicionais a classes, métodos, acessores, propriedades ou parâmetros. Os decoradores são uma ferramenta poderosa para melhorar a legibilidade e reutilização do código.
Noções básicas de decoradores
Um decorador é uma função que injeta funcionalidades adicionais em uma classe ou em membros da classe. Os decoradores foram introduzidos no TypeScript 1.5 e também foram propostos para o padrão ECMAScript.
1{
2 "compilerOptions": {
3 "experimentalDecorators": true
4 }
5}
- Para usar os decoradores, é necessário habilitar a opção
experimentalDecorators
no arquivotsconfig.json
.
Tipos de decoradores
No TypeScript, você pode usar os cinco decoradores a seguir.
- Decorador de Classe Um decorador aplicado a uma classe.
- Decorador de Método Um decorador aplicado a um método de uma classe.
- Decorador de Acessor Um decorador aplicado a um getter ou setter de uma propriedade de classe.
- Decorador de Propriedade Um decorador aplicado a uma propriedade de uma classe.
- Decorador de Parâmetro Um decorador aplicado a um parâmetro de um método.
Decorador de Classe
Os decoradores de classe são decoradores aplicados a classes. Os decoradores de classe são escritos logo acima da definição da classe e podem acessar o construtor da classe. Eles são usados principalmente para alterar o comportamento da classe ou adicionar metadados.
1function Logger(constructor: Function) {
2 console.log(`Class ${constructor.name} is being constructed`);
3}
4
5@Logger
6class Person {
7 constructor(public name: string) {}
8}
9
10const person = new Person('John');
11// Output: Class Person is being constructed
Neste exemplo, o decorador Logger
é aplicado à classe e uma mensagem é exibida no console quando a classe é inicializada.
Decorador de Método
Os decoradores de método são aplicados aos métodos de classe e podem alterar as chamadas e o comportamento dos métodos. Um decorador de método recebe três argumentos.
- O protótipo da classe
- O nome do método
- O descritor de propriedade do método
1function LogExecutionTime(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
2 const originalMethod = descriptor.value;
3
4 descriptor.value = function (...args: any[]) {
5 console.time(propertyKey);
6 const result = originalMethod.apply(this, args);
7 console.timeEnd(propertyKey);
8 return result;
9 };
10}
11
12class MathOperations {
13 @LogExecutionTime
14 add(a: number, b: number): number {
15 return a + b;
16 }
17}
18
19const math = new MathOperations();
20math.add(2, 3);
21// Output: add: 0.000ms (execution time is displayed)
Neste exemplo, o decorador LogExecutionTime
é aplicado ao método, e o tempo de execução do método é registrado.
Decorador de Acessor
Os decoradores de acessor são aplicados ao getter
ou setter
das propriedades da classe. Eles são úteis para adicionar comportamento ao alterar os valores de propriedades.
1function LogAccess(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
2 const originalGet = descriptor.get;
3 const originalSet = descriptor.set;
4
5 if (originalGet) {
6 descriptor.get = function () {
7 console.log(`Getter called for ${propertyKey}`);
8 return originalGet.call(this);
9 };
10 }
11
12 if (originalSet) {
13 descriptor.set = function (value: any) {
14 console.log(`Setter called for ${propertyKey} with value: ${value}`);
15 originalSet.call(this, value);
16 };
17 }
18}
19
20class Car {
21 private _speed: number = 0;
22
23 @LogAccess
24 get speed() {
25 return this._speed;
26 }
27
28 set speed(value: number) {
29 this._speed = value;
30 }
31}
32
33const car = new Car();
34car.speed = 120; // Setter called for speed with value: 120
35console.log(car.speed); // Getter called for speed → 120
Neste exemplo, um decorador de acessor é usado para registrar (logar) a saída quando o getter
e o setter
são chamados.
Decorador de Propriedade
Os decoradores de propriedade são aplicados às propriedades da classe, mas não podem alterar diretamente o valor ou comportamento da propriedade. Eles são usados para obter metadados de propriedades.
1function Readonly(target: any, propertyKey: string) {
2 Object.defineProperty(target, propertyKey, {
3 writable: false
4 });
5}
6
7class Book {
8 @Readonly
9 title: string = "TypeScript Guide";
10}
11
12const book = new Book();
13book.title = "New Title"; // Error: Cannot assign to read only property 'title'
Neste exemplo, o decorador Readonly
é aplicado à propriedade title
, e a propriedade é tornada somente leitura.
Decorador de Parâmetro
Os decoradores de parâmetro são aplicados aos parâmetros de um método. Eles geralmente são usados para armazenar metadados ou validar parâmetros. Os decoradores recebem três argumentos.
- O protótipo da classe
- O nome do método
- Índice do Parâmetro
1function LogParameter(target: any, propertyKey: string, parameterIndex: number) {
2 console.log(`Parameter at index ${parameterIndex} in method ${propertyKey} was decorated.`);
3}
4
5class User {
6 greet(@LogParameter message: string) {
7 console.log(message);
8 }
9}
10
11const user = new User();
12user.greet('Hello!');
13// Output: Parameter at index 0 in method greet was decorated.
Neste exemplo, o decorador LogParameter
é aplicado ao primeiro parâmetro do método greet
, e quando o método é chamado, registra que o parâmetro está decorado.
Exemplos Práticos de Decoradores
Os decoradores são amplamente usados em frameworks como Angular, especialmente para injeção de dependência e definição de metadados. Por exemplo, use o decorador @Component
para definir componentes Angular, como mostrado abaixo.
1@Component({
2 selector: 'app-root',
3 template: '<h1>Hello World</h1>',
4})
5export class AppComponent {}
Assim, os decoradores são frequentemente usados como partes centrais de frameworks e bibliotecas, ajudando a manter o código conciso e claro.
Resumo dos Decoradores
Os decoradores do TypeScript são ferramentas poderosas que adicionam funcionalidade de forma flexível a classes, métodos e propriedades. O uso de decoradores personalizados melhora a manutenibilidade e a reutilização do código, permitindo maior abstração. Os decoradores desempenham um papel importante em frameworks como Angular e NestJS, e entendê-los ajuda a compreender profundamente como esses frameworks funcionam.
Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.