TypeScript Decorators : classes, méthodes et propriétés
Les TypeScript Decorators (décorateurs TypeScript) permettent d’ajouter des fonctions supplémentaires à des objets, et ce sans devoir modifier le code source. Ils peuvent être appliqués aux classes, aux méthodes, aux propriétés, aux fonctions d’accès et aux paramètres, et accèdent aux annotations et métadonnées.
Les TypeScript Decorators : c’est quoi et à quoi ça sert ?
Le principe des TypeScript Decorators n’a fondamentalement rien de nouveau. On trouve des concepts similaires dans d’autres langages de programmation comme les attributs en C#, les décorateurs en Python ou les annotations en Java. Il s’agit de pouvoir étendre les fonctions d’un objet sans en modifier le code source. TypeScript aussi travaille depuis longtemps selon cette approche. Certes, la plupart des navigateurs ne supportent pas (encore) les TypeScript Decorators, mais il est tout de même intéressant d’essayer cette méthode et ses possibilités. Depuis la version TypeScript 5.0, leur utilisation a été considérablement simplifiée.
Les TypeScript Decorators sont utilisés pour ajouter des annotations et des métadonnées supplémentaires aux classes TypeScript et aux éléments. Outre les classes, il est possible de modifier les méthodes, les propriétés, les méthodes d’accès ainsi que les paramètres. Ces derniers peuvent être contrôlés et leurs valeurs consultées. Il s’agit de l’une des grandes différences entre les TypeScript Decorators et leur équivalent pour JavaScript.
- Sécurité des données
- Outils de collaboration intégrés
- Hébergement dans des data centers européens
Syntaxe et fonctionnement des décorateurs
En ajoutant des TypeScript Decorators à un objet, vous appelez une fonction qui peut être exécutée sans modification du code source. Vous augmentez ainsi la fonctionnalité tout en gardant un code clair. La syntaxe de base est la suivante :
@nomDuDecorateur
typescriptVous pouvez créer cette fonction avec deux ou trois paramètres. La syntaxe de la fonction à trois paramètres prend la forme suivante :
function decoratorFonction(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(`Decorating ${propertyKey} of class ${target.constructor.name}`);
}
class MyClass {
@decoratorFonction
myMethod() {
}
}
typescriptLes différents éléments des TypeScript Decorators sont les suivants :
target
: désigne l’objet auquel le décorateur a été attribuépropertyKey
: est un string contenant le nom de la classe à laquelle un décorateur a été attribué ; il peut s’agir, entre autres, de méthodes ou de propriétésdescriptor
: permet de stocker des informations supplémentaires sur l’objet sur lequel le décorateur est appliqué ; les propriétés possibles sontvalue
,writable
,enumerable
ouconfigurable
.
Voici, ci-dessous, la syntaxe des TypeScript Decorators a deux paramètres :
function decoratorFonction(target: any) {
console.log(`Decorating ${target.name}`);
}
@decoratorFonction
class MyClass {
}
typescriptDans ce cas, les TypeScript Decorators ont été appliqués à une classe.
Les différents types de décorateurs
Il existe différents types de TypeScript Decorators. Nous les présentons plus en détail ci-après, avec leurs particularités respectives :
- Class Decorators
- Method Decorators
- Property Decorators
- Accessor Decorators
- Parameter Decorators
TypeScript Decorators pour les classes
Les TypeScript Decorators permettent d’adapter les caractéristiques d’une classe et de modifier son constructeur, ses méthodes ou ses propriétés. Dès que vous « décorez » la classe avec une fonction, vous recevez le constructeur comme premier paramètre. Voici un exemple de code traitant d’une liste de clients. Elle a quelques propriétés privées et publiques :
class Client {
private static userType: string = "Generic";
private _email: string;
public nomduclient: string;
public rue: string = "";
public lieuderesidence: string = "";
public pays: string = "";
constructor(nomduclient: string, email: string) {
this.nomduclient = nomduclient;
this._email = email;
}
static get userType() {
return Client.userType;
}
get email() {
return this._email;
}
set email(nouvelemail: string) {
this._email = nouvelemail;
}
adresse(): string {
return `${this.rue}\n${this.lieuderesidence}\n${this.pays}`;
}
}
const p = new Client("clientexemple", "name@exemple.com");
p.rue = "6 rue de Drulingen";
p.lieuderesidence = "Strasbourg";
typescriptDans l’étape suivante, nous utilisons les TypeScript Decorators pour ajouter d’autres fonctions qui ne modifient toutefois pas le code source après coup. Nous ajoutons ainsi le décorateur @frozen
pour la classe « Client ». Cette fonction fait en sorte que les objets ne puissent pas être modifiés ultérieurement. Pour certaines propriétés, nous utilisons @required
pour indiquer explicitement la saisie. Nous utilisons aussi @enumerable
pour les énumérations et @deprecated
pour les entrées obsolètes. Voyons tout d’abord ensemble la définition des décorateurs :
function frozen(constructor: Function) {
Object.freeze(constructor);
Object.freeze(constructor.prototype);
}
function required(target: any, propertyKey: string) {
}
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.`);
}
typescriptAprès l’utilisation des TypeScript Decorators, le code résultant a la syntaxe suivante :
@frozen
class Client {
private static userType: string = "Generic";
@required
private _email: string;
@required
public nomduclient: string;
public rue: string = "";
public lieuderesidence: string = "";
public pays: string = "";
constructor(nomduclient: string, email: string) {
this. nomduclient = nomduclient;
this._email = email;
}
@enumerable(false)
static get userType() {
return Client.userType;
}
get email() {
return this._email;
}
set email(nouvelemail: string) {
this._email = nouvelemail;
}
@deprecated
adresse(): string {
return `${this.rue}\n${this.lieuderesidence}\n${this.pays}`;
}
}
const p = new Client("clientexemple", "nom@exemple.com");
p.rue = "6 rue de Drulingen";
p.lieuderesidence = "Strasbourg";
typescriptTypeScript Decorators pour les méthodes
L’utilisation de TypeScript Decorators est également possible pour les méthodes, exception faite des fichiers de déclaration, de l’overloading (surcharge de fonction) ou de la classe « Declare ». Dans l’exemple suivant, nous utilisons @enumerable
comme décorateur pour la méthode getName
dans la classe « Personne » :
const enumerable = (value: boolean) => {
return (target: any, propertyKey: string, propertyDescriptor: PropertyDescriptor) => {
propertyDescriptor.enumerable = value;
}
}
class Personne {
prenom: string = "Julie"
nom: string = "Rault"
@enumerable(true)
getName () {
return `${this.prenom} ${this.nom}`;
}
}
typescriptTypeScript Decorators pour les propriétés
Les TypeScript Decorators pour les propriétés d’une classe (Property Decorators) ont deux paramètres : la fonction de constructeur de la classe et le nom de la propriété. Dans l’exemple suivant, nous utilisons le décorateur pour afficher le nom d’une propriété (ici le nom du client) :
const printPropertyName = (target: any, propertyName: string) => {
console.log(propertyName);
};
class Client {
@printPropertyName
name: string = "Julie";
}
typescriptTypeScript Decorators pour les fonctions d’accès
Les Accessor Decorators fonctionnent selon un principe très similaire à celui des Property Decorators. À la différence de ces derniers, ils ont un troisième paramètre en plus. Dans notre exemple, il s’agit du Property Descriptor pour un client. En indiquant une valeur avec l’Accessor Decorator, celui-ci devient le nouveau Property Descriptor. Dans le code suivant, la valeur booléenne (« True » ou « False ») de enumerable
est ainsi modifiée.
const enumerable = (value: boolean) => {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
descriptor.enumerable = value;
}
}
typescriptVoici comment appliquer le décorateur :
class Client {
prenom: string = "Julie";
nom: string = "Rault";
@enumerable(true)
get name() {
return `${this.prenom} ${this.nom}`;
}
}
typescriptTypeScript Decorators pour les paramètres
Les TypeScript Decorators de type Parameter Decorator disposent également de trois paramètres : la fonction de constructeur de classe, le nom de la méthode et en plus une désignation d’index du paramètre. Toutefois, le paramètre en soi ne peut pas être modifié, de sorte que ce décorateur peut être utilisé uniquement pour la vérification. Si vous souhaitez, par exemple, consulter l’index, faites-le avec ce code :
function print(target: Object, propertyKey: string, parameterIndex: number) {
console.log(`Decorating param ${parameterIndex} from ${propertyKey}`);
}
typescriptSi vous appliquez ensuite le paramètre Décorateur, le code est le suivant :
class Exemple {
testMethod(param0: any, @print param1: any) {}
}
typescriptIdéal pour les sites Internet statiques et les applications : avec Deploy Now de IONOS, vous bénéficiez d’un environnement de simulation (staging) simple, d’une installation rapide et de workflows parfaitement harmonisés. Trouvez le modèle le mieux adapté à vos besoins !