Agora escreva um código mais limpo e inteligente

TypeScript é uma linguagem de programação fortemente tipada baseada em JavaScript, oferecendo melhores ferramentas em escala. TypeScript foi desenvolvido para ajudar a resolver alguns dos problemas que surgem ao escrever código usando JavaScript. TypeScript supera as armadilhas do JavaScript por meio do uso de tipos.

Cada valor em um código-fonte TypeScript possui um tipo. O TypeScript verifica se cada valor segue as regras associadas ao seu tipo. O TypeScript verifica erros em seu código-fonte sem que você precise executar ou executar seu programa.

Isso é chamado de verificação de tipo estático, que envolve a verificação de erros de desenvolvimento com base no tipo de valores usados ​​em um programa.

Além de ajudá-lo a escrever código mais claro e legível e fornecer verificação de tipo estático, o TypeScript oferece recursos adicionais para ajudar na legibilidade, reutilização e manutenção do código. Um desses recursos são os decoradores TypeScript.

Decoradores TypeScript

Decoradores em TypeScript são um recurso que permite alterar ou aprimorar o comportamento do seu código em tempo de execução ou adicionar metadados ao seu código. Decoradores permitem metaprogramação em TypeScript. Metaprogramação é uma técnica de programação onde programas podem tratar outros programas como seus dados e assim modificar seu comportamento.

Essencialmente, decoradores são funções que serão chamadas para executar alguma lógica em tempo de execução quando os elementos decorados forem acessados ​​ou modificados.

Desta forma, funcionalidades adicionais podem ser adicionadas aos elementos decorados. Decoradores TypeScript podem ser anexados a declarações de classe, métodos, propriedades, acessadores (getters e setters) e parâmetros de método.

No TypeScript, os decoradores são prefixados com o símbolo @ e assumem a forma de @expression com expressão avaliada para uma função que será chamada em tempo de execução. A sintaxe geral para usar decoradores em TypeScript é mostrada abaixo:

@decoratorName
itemToDecorate

Um exemplo de decorador de classe simples é mostrado abaixo:

function logClass(target: Function) {
  console.log("The Log Class Decorator has been called")
  console.log("Class:", target);
}

@logClass // @logClass is a decorator
class MyClass {
  constructor() {
    console.log("An instance of MyClass has been created");
  }
}

const myInstance = new MyClass();

O resultado da execução do código acima é mostrado abaixo:

Saída:

The Log Class Decorator has been called
Class: [class MyClass]
An instance of MyClass has been created

A função logClass() recebe um único argumento chamado target do tipo Function. O argumento target é do tipo Function porque receberá o construtor da classe que estamos decorando.

Para usar logClass() como decorador para decorar a classe chamada MyClass colocamos @logclass logo antes da declaração de MyClass. O decorador deve ter o mesmo nome da função que você deseja usar para decorar um elemento.

Quando uma instância de MyClass é criada, o comportamento do decorador é executado além do construtor da classe, conforme mostrado na saída.

  Como habilitar suplementos e conectores no Outlook

Os decoradores estão atualmente disponíveis no Typescript como um recurso experimental. Portanto, para usar decoradores no TypeScript, você precisa habilitar a opção experimentalDecorators in the compiler no arquivo tsconfig.json.

Para fazer isso, gere um arquivo tsconfig.json na pasta do projeto TypeScript executando o seguinte comando no terminal aberto no diretório do projeto:

tsc --init

Assim que tiver um arquivo tsconfig.json, abra-o e descomente experimentalDecorators conforme mostrado abaixo:

Além disso, defina sua versão de destino do JavaScript para pelo menos ES2015.

Importância dos decoradores TypeScript

Um bom código pode ser facilmente determinado pela legibilidade, reutilização e manutenção do código. Código legível é um código fácil de entender e interpretar e que comunica claramente a intenção do desenvolvedor para quem está lendo o código.

O código reutilizável, por outro lado, é o código que permite que componentes específicos, como funções e classes, sejam reaproveitados, adaptados e usados ​​em outras partes de um aplicativo ou em um aplicativo completamente novo, sem modificações significativas.

Código sustentável é aquele que pode ser facilmente modificado, atualizado e corrigido ao longo de sua vida útil.

Os decoradores TypeScript permitem que você obtenha legibilidade, reutilização e manutenção do código. Primeiro, os decoradores TypeScript permitem aprimorar o comportamento do seu código usando uma sintaxe declarativa que é mais fácil de ler. Você pode encapsular a lógica em decoradores e invocá-los decorando diferentes elementos do seu código onde você precisa da lógica.

Isso torna seu código fácil de ler e entender o que está acontecendo. Os decoradores comunicam claramente a intenção do desenvolvedor.

Os decoradores não são elementos descartáveis; eles são reutilizáveis ​​por natureza. Você pode criar um decorador uma vez e usá-lo diversas vezes em diversas áreas.

Portanto, você pode definir decoradores, importá-los e usá-los em qualquer lugar da sua base de código onde desejar modificar o comportamento do seu código. Isso é benéfico porque permite evitar a duplicação de lógica na sua base de código, aumentando assim a capacidade de reutilização do seu código.

Os decoradores também oferecem muita flexibilidade e modularidade ao seu código, permitindo separar diferentes funcionalidades em componentes independentes. Isso, aliado ao fato de permitirem a escrita de código legível e reutilizável, significa que os decoradores TypeScript permitirão que você tenha um código fácil de manter.

Tipos de decoradores TypeScript

Conforme observado anteriormente, os decoradores TypeScript podem ser anexados a classes, propriedades de classe, métodos de classe, acessadores de classe e parâmetros de método de classe. Dos elementos que podemos decorar, obtemos os diferentes tipos de decoradores TypeScript. Esses decoradores incluem:

#1. Decorador de aula

Um decorador de classe é um decorador usado para observar, modificar ou substituir uma definição de classe. É declarado pouco antes da aula que está decorando. Um decorador de classe é aplicado ao construtor da classe que está decorando. Em tempo de execução, um decorador de classe será chamado com o construtor da classe que está decorando como único argumento.

  11 melhores dispositivos de monitoramento da qualidade do ar para pulmões mais frescos

Um decorador de classe usado para evitar que uma classe seja estendida é mostrado abaixo:

function frozen(target: Function) {
  Object.freeze(target);
  Object.freeze(target.prototype)
}

@frozen
class Vehicle {
  wheels: number = 4;
  constructor() {
    console.log("A vehicle has been created")
  }
}

class Car extends Vehicle {
  constructor() {
    super();
    console.log("A car has been created");
  }
}

console.log(Object.isFrozen(Vehicle));

Para evitar que uma classe seja estendida, usamos a função Object.freeze() e passamos a classe que queremos congelar. Um decorador é usado para adicionar essa funcionalidade a uma classe. Podemos verificar se a classe Vehicle está congelada em tempo de execução passando a classe para isFrozen(), a saída do código é mostrada abaixo:

true

#2. Decorador de imóveis

Um decorador de propriedade é usado para decorar uma propriedade de classe e é declarado logo antes da decoração da propriedade. Os decoradores de propriedades podem ser usados ​​para alterar ou observar uma definição de propriedade.

Em tempo de execução, o decorador será chamado e recebe dois argumentos. Primeiro, a função construtora da classe se o membro for estático ou o protótipo da classe caso seja um membro de instância. O segundo argumento é o nome do sócio, ou seja, o imóvel que você está decorando.

No TypeScript, os membros estáticos têm a palavra-chave static antes deles. Membros estáticos podem ser acessados ​​sem instanciar uma classe. Os membros da instância não possuem a palavra-chave static antes deles e só podem ser acessados ​​após a criação de uma instância de uma classe.

Um exemplo de decorador de propriedade é mostrado abaixo:

function wheelsDecorator(target: any, propertyName: string) {
  console.log(propertyName.toUpperCase())
}

class Vehicle {
  @wheelsDecorator
  wheels: number = 4;
  constructor() {
    console.log("A vehicle has been created")
  }
}

A saída da execução do código é mostrada abaixo:

WHEELS

#3. Decorador de métodos

Um decorador de método, declarado logo antes da declaração de um método, é um decorador usado para observar, modificar ou substituir uma definição de método. Recebe três argumentos, a função construtora da classe caso o membro seja estático ou a propriedade da classe se for um membro de instância.

O segundo argumento é o nome do membro e, finalmente, um descritor de propriedade para o membro. Um descritor de propriedade é um objeto associado às propriedades do objeto e fornece informações sobre os atributos e o comportamento de uma propriedade.

Os decoradores de método são úteis quando você deseja executar alguma ação antes ou depois de um método ser chamado. Também podemos usá-los para registrar informações sobre o método que está sendo chamado. Isso pode ser útil caso você queira informar a um usuário que um método está obsoleto; ou seja, ele ainda está disponível para uso, mas não é recomendado que você o utilize, pois poderá ser removido posteriormente.

  Como instalar o WordPress no localhost para teste e desenvolvimento?

Um exemplo de decorador de método é mostrado abaixo:

const logDeprecated =(target: any, methodName: string, descriptor: PropertyDescriptor) => {
  console.log(`${methodName} has been deprecated`)
  console.log(descriptor);
}

class Vehicle {
  wheels: number = 4;
  constructor() {
    console.log("A vehicle has been created")
  }
  @logDeprecated
  reFuel(): void {
    console.log("Your vehicle is being refuelled");
  }
}

Saída:

reFuel has been deprecated
{
  value: [Function: reFuel],
  writable: true,
  enumerable: false,
  configurable: true
}

#4. Decoradores de acessórios

No TypeScript, existem dois tipos de métodos acessadores, get e set. Os métodos de acesso são usados ​​para controlar o acesso às propriedades da classe. Decoradores de acesso são usados ​​para decorar esses dois métodos de acesso e são declarados logo antes da declaração do acessador. Como os acessadores ainda são métodos, os decoradores de acessadores funcionam exatamente como os decoradores de métodos.

Um exemplo de decoradores de acesso é mostrado abaixo:

const logWheels =(target: any, accessorName: string, descriptor: PropertyDescriptor) => {
  console.log(`${accessorName} used to get the number of wheels`)
  console.log(descriptor);
}

class Vehicle {
  private wheels: number = 4;
  constructor() {
    console.log("A vehicle has been created")
  }
  @logWheels
  get numWheels(): number {
    return this.wheels;
  }
}

Saída:

numWheels used to get the number of wheels
{
  get: [Function: get numWheels],
  set: undefined,
  enumerable: false,
  configurable: true
}

Com decoradores de acessadores, é importante observar que os decoradores não podem ser aplicados a vários acessadores get/set com o mesmo nome. Por exemplo, em nosso exemplo de código acima, se você criar um setter chamado set numWheels, não poderá usar o decorador logWheels nele.

#5. Decoradores de parâmetros

Um decorador de parâmetro é usado para observar se um parâmetro foi declarado em um método e é declarado antes da declaração de um parâmetro. Os decoradores de parâmetros recebem três argumentos: primeiro, a função construtora da classe para um membro estático ou o protótipo da classe para um membro de instância.

O segundo argumento é o nome do membro, ou seja, o nome do parâmetro. O terceiro argumento é o índice ordinal do parâmetro na lista de parâmetros da função. Ou seja, na lista de parâmetros, em que posição está o parâmetro, estando o primeiro parâmetro no índice 0?

Um exemplo de decorador de parâmetros é mostrado abaixo:

const passengerLog = (target: Object, propertyKey: string, parameterIndex: number) => {
  console.log(`Decorator on ${propertyKey}'s paremeter index ${parameterIndex}`);
}

class Vehicle {
  private wheels: number = 4;
  constructor() {
    console.log("A vehicle has been created")
  }
  pickPassenger( location: string, numPassengers: string, @passengerLog driver: string) {
    console.log(`${numPassengers} picked at ${location} by ${driver}`)
  }
  dropPassenger(driver: string, @passengerLog location: string, numPassengers: string) {
    console.log(`${numPassengers} dropped at ${location} by ${driver}`)
  }
}

Saída:

Decorator on pickPassenger's paremeter index 2
Decorator on dropPassenger's paremeter index 1

Conclusão

Os decoradores TypeScript percorrem um longo caminho para melhorar a legibilidade do código e ajudá-lo a escrever código modular e reutilizável, já que você pode declarar decoradores uma vez e usá-los muitas vezes. Além disso, os decoradores contribuem para a manutenção geral do seu código.

Por mais que ainda sejam um recurso experimental, os decoradores são muito úteis e você definitivamente deveria considerar se familiarizar com eles.

Você também pode ler como converter uma string em um número no TypeScript.