# Decoratori di TypeScript: classi, metodi e proprietà

I decoratori in TypeScript sono un modo pratico e semplice per assegnare funzionalità aggiuntive agli oggetti senza modificare il codice sorgente. È possibile utilizzarli su classi, metodi, proprietà, funzioni di accesso e parametri, così da accedere ad annotazioni e metadati.

## Che cosa sono i decoratori di TypeScript e a cosa servono?

Il principio dei decoratori di TypeScript non è del tutto nuovo. In altri [linguaggi di programmazione](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/quale-linguaggio-di-programmazione-imparare/) sono disponibili funzionalità simili, ad esempio gli attributi in C#, i [decoratori in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/decoratori-python/) o le annotazioni in Java. Si tratta di possibilità per **espandere le funzionalità di un oggetto** senza modificare il codice sorgente. Anche [TypeScript](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/typescript/) sfrutta questo principio già da tempo. Anche se la maggior parte dei browser non supporta (ancora) i decoratori di TypeScript, vale comunque la pena sperimentare questo approccio e le sue possibilità. A partire dalla versione 5.0, l’uso dei decoratori è stato notevolmente semplificato.

I decoratori di TypeScript sono utilizzati per creare **annotazioni e metadati aggiuntivi** per le [classi di TypeScript](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/classi-di-typescript/) e per aggiungere elementi. Oltre alle classi è possibile modificare anche metodi, proprietà, metodi di accesso e parametri. Questi ultimi possono essere verificati ed è possibile richiamarne i valori. Anche questa è una grande differenza tra i decoratori di TypeScript e il loro equivalente per JavaScript.

## Sintassi e funzionamento dei decoratori

Quando aggiungi i decoratori di TypeScript a un oggetto, in realtà stai richiamando una [funzione](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/funzioni-di-typescript/) che può essere eseguita **senza modificare il codice sorgente**. Ciò aumenta la funzionalità e preserva comunque la chiarezza del codice. La sintassi di base si presenta così:

```typescript
@nomeDecoratore
```

È possibile creare questa funzione con due o tre parametri. La sintassi per la funzione con tre parametri si presenta simile a questa:

```typescript
function FunzioneDecoratore(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log(`Decorating ${propertyKey} of class ${target.constructor.name}`);
}
class MyClass {
    @FunzioneDecoratore
    myMethod() {
    }
}
```

I singoli componenti dei decoratori di TypeScript sono costituiti da questi elementi:

- `target`: `target` indica l’oggetto a cui è stato assegnato il decoratore
- `propertyKey`: `propertyKey` è una stringa contenente il nome della classe a cui è stato assegnato un decoratore; tra le varie opzioni, è possibile inserire metodi o proprietà
- `descriptor`: in `descriptor` è possibile inserire ulteriori informazioni sull’oggetto a cui si applica il decoratore; le proprietà possibili sono `value`, `writable`, `enumerable` o `configurable`.

La sintassi dei decoratori in TypeScript con due parametri è la seguente:

```typescript
function FunzioneDecoratore(target: any) {
    console.log(`Decorating ${target.name}`);
}
@FunzioneDecoratore
class MyClass {
}
```

In questo caso, i decoratori di TypeScript sono stati applicati a una classe.

## I diversi tipi di decoratori

Esistono diversi tipi di decoratori di TypeScript, ciascuno dotato di caratteristiche particolari e che descriveremo in dettaglio più avanti nell’articolo:

- Decoratori di classe
- Decoratori di metodo
- Decoratori di proprietà
- Decoratori di accessor
- Decoratori di parametri

## Decoratori di TypeScript per classi

I decoratori di TypeScript ti permettono di **personalizzare le proprietà di una classe** e modificarne il costruttore, i metodi o le proprietà. Come primo parametro accettano il costruttore non appena si “decora” la classe con una funzione. Quello che segue è un codice di esempio in cui lavoriamo con un elenco di clienti. Qui si possono notare alcune proprietà private e altre pubbliche:

```typescript
class Clienti {
    private static userType: string = "Generic";
    private _email: string;
    public nomecliente: string;
    public via: string = "";
    public località: string = "";
    public paese: string = "";
    constructor(nomecliente: string, email: string) {
        this.nomecliente = nomecliente;
        this._email = email;
    }
    Static get userType() {
        return Clienti.userType;
    }
    get email() {
        return this._email;
    }
    set email(emailnuova: string) {
        this._email = emailnuova;
    }
    indirizzo(): string {
        return `${this.via}\n${this.località}\n${this.paese}`;
    }
}
const p = new Clienti("esempiocliente", "nome@esempio.com");
p.via = "Via Garibaldi 2";
p.località = "Roma";
```

Nel passaggio successivo utilizzeremo quindi i decoratori di TypeScript per aggiungere funzioni supplementari che tuttavia non vanno poi a modificare il codice sorgente. Aggiungiamo quindi il decoratore `@frozen` per la classe “Clienti”. Questa funzione fa sì che gli oggetti non possano essere modificati successivamente. Per alcune proprietà utilizziamo `@required` per dare istruzioni esplicite all’input. Utilizziamo inoltre `@enumerable` per gli elenchi e `@deprecated` per gli input obsoleti. Per prima cosa ci occupiamo della definizione dei decoratori:

```typescript
function frozen(constructor: Function) {
    Object.freeze(constructor);
    Object.freeze(constructor.prototype);
}
function required(target: any, propertyKey: string) {
    // Logica per il decoratore Required
}
function enumerable(value: boolean) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        descriptor.enumerable = value;
    };
}
function deprecated(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.warn(`The method ${propertyKey} is deprecated.`);
}
```

Dopo l’utilizzo dei decoratori di TypeScript, il codice finale si presenta così:

```typescript
@frozen
class Clienti {
    private static userType: string = "Generic";
    @required
    private _email: string;
    @required
    public nomecliente: string;
    public via: string = "";
    public località: string = "";
    public paese: string = "";
    constructor(nomecliente: string, email: string) {
        this.nomecliente = nomecliente;
        this._email = email;
    }
    @enumerable(false)
    get userType() {
        return Clienti.userType;
    }
    get email() {
        return this._email;
    }
    set email(emailnuova: string) {
        this._email = emailnuova;
    }
    @deprecated
    indirizzo(): string {
        return `${this.via}\n${this.località}\n${this.paese}`;
    }
}
const p = new Clienti("esempiocliente", "nome@esempio.com");
p.via = "Via Garibaldi, 2";
p.località = "Roma";
```

## Decoratori di TypeScript per metodi

È possibile utilizzare i decoratori di TypeScript anche per i **metodi**. Fanno eccezione solo i file di dichiarazione, l’overloading e la classe “declare”. Nell’esempio seguente utilizziamo `@enumerable` come decoratore per il metodo `getName` nella classe “Person”:

```typescript
const enumerable = (value: boolean) => {
    return (target: any, propertyKey: string, propertyDescriptor: PropertyDescriptor) => {
        propertyDescriptor.enumerable = value;
    }
}
class Person {
    nome: string = "Giulia"
    cognome: string = "Rossi"
    @enumerable(true)
    getName () {
        return `${this.nome} ${this.cognome}`;
    }
}
```

## Decoratori di TypeScript per proprietà

I decoratori di TypeScript per le proprietà di una classe (decoratori di proprietà) possono avere due parametri: la funzione costruttore della classe e il nome della proprietà. Nell’esempio seguente utilizziamo il decoratore per restituire il nome di una proprietà (in questo caso il nome del cliente):

```typescript
const printPropertyName = (target: any, propertyName: string) => {
    console.log(propertyName);
};
class Clienti {
    @printPropertyName
    name: string = "Giulia";
}
```

## Decoratori di TypeScript per funzioni di accesso

I decoratori di accessor funzionano secondo un principio molto simile ai decoratori di proprietà. Rispetto a questi ultimi hanno un **terzo parametro aggiuntivo**. Nel nostro esempio, questo parametro è il descrittore di proprietà per un cliente. A questo punto, se si restituisce un valore utilizzando il decoratore di accessor, il valore diventa il nuovo descrittore della proprietà. Il codice seguente cambia quindi il valore booleano (“true” o “false”) di `enumerable`. Il nostro punto di partenza è il seguente:

```typescript
const enumerable = (value: boolean) => {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        descriptor.enumerable = value;
    }
}
```

Il decoratore si utilizza con questo codice:

```typescript
class Clienti {
    nome: string = "Giulia";
    cognome: string = "Rossi";
    @enumerable(true)
    get name() {
        return `${this.nome} ${this.cognome}`;
    }
}
```

## Decoratori di TypeScript per parametri

Anche i **decoratori di parametri** in TypeScript presentano tre parametri: la funzione di costruttore della classe, il nome del metodo e un nome di indice per il parametro. Tuttavia, il parametro stesso non può essere modificato: pertanto questo decoratore può essere utilizzato **solo a scopo di verifica**. Se, ad esempio, intendi interrogare l’indice, puoi farlo con questo codice:

```typescript
function print(target: Object, propertyKey: string, parameterIndex: number) {
    console.log(`Decorating param ${parameterIndex} from ${propertyKey}`);
}
```

Se poi vuoi applicare il decoratore di parametro, il codice è questo:

```typescript
class Esempio {
    testMethod(param0: any, @print param1: any) {}
}
```

Consiglio L’ideale per i siti web statici e per le app: [Deploy Now](https://www.ionos.it/hosting/deploy-now "Deploy Now di IONOS") di IONOS mette a tua disposizione un facile staging, una configurazione veloce e flussi di lavoro perfettamente coordinati. Trova il modello giusto per le tue esigenze!


This is a markdown version of: [https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/decoratori-di-typescript/](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/decoratori-di-typescript/) for AI/LLM consumption.