Decorators in TypeScript
Dit artikel legt decorators in TypeScript uit.
YouTube Video
Decorators in TypeScript
TypeScript-decorators zijn een mechanisme om aanvullende functionaliteit of gedrag toe te voegen aan klassen, methoden, toegangselementen, eigenschappen of parameters. Decorators zijn een krachtig hulpmiddel om de leesbaarheid en herbruikbaarheid van code te verbeteren.
Basisprincipes van Decorators
Een decorator is een functie die aanvullende functionaliteit injecteert in een klasse of klasseleden. Decorators werden geïntroduceerd in TypeScript 1.5 en zijn ook voorgesteld voor de ECMAScript-standaard.
1{
2 "compilerOptions": {
3 "experimentalDecorators": true
4 }
5}
- Om decorators te gebruiken, moet je de optie
experimentalDecorators
inschakelen in hettsconfig.json
-bestand.
Soorten Decorators
In TypeScript kun je de volgende vijf decorators gebruiken.
- Klasse-decorator Een decorator die op een klasse wordt toegepast.
- Methode-decorator Een decorator die op een methode van een klasse wordt toegepast.
- Accessor-decorator Een decorator die wordt toegepast op een getter of setter van een klasse-eigenschap.
- Eigenschap-decorator Een decorator die op een eigenschap van een klasse wordt toegepast.
- Parameter-decorator Een decorator die op een parameter van een methode wordt toegepast.
Klasse Decorator
Klasse-decorators zijn decorators die worden toegepast op klassen. Klasse-decorators worden direct boven de klasse-definitie geschreven en hebben toegang tot de klasseconstructor. Ze worden voornamelijk gebruikt om het gedrag van een klasse te wijzigen of metadata toe te voegen.
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
In dit voorbeeld wordt de Logger
decorator toegepast op de klasse en wordt er een bericht weergegeven in de console wanneer de klasse wordt geïnitialiseerd.
Methode Decorator
Methode-decorators worden toegepast op klassemethode en kunnen method oproepen en gedrag veranderen. Een methode-decorator neemt drie argumenten.
- Het prototype van de klasse
- De naam van de methode
- De eigenschapdescriptor van de methode
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)
In dit voorbeeld wordt de LogExecutionTime
decorator toegepast op de methode, en de uitvoeringstijd van de methode wordt gelogd.
Toegangsdecorator
Toegangsdecorators worden toegepast op getter
of setter
van klasse-eigenschappen. Ze zijn nuttig om gedrag toe te voegen bij het wijzigen van eigenschapswaarden.
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
In dit voorbeeld wordt een accessordecorator gebruikt om output te loggen wanneer de getter
en setter
worden aangeroepen.
Eigenschapsdecorator
Eigenschapsdecorators worden toegepast op klasse-eigenschappen, maar kunnen de waarde of het gedrag van de eigenschap niet direct wijzigen. Ze worden gebruikt om metadata van eigenschappen te verkrijgen.
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'
In dit voorbeeld wordt de Readonly
decorator toegepast op de title
eigenschap, en wordt de eigenschap alleen-lezen gemaakt.
Parameterdecorator
Parameterdecorators worden toegepast op de parameters van een methode. Ze worden meestal gebruikt om metadata op te slaan of parameters te valideren. Decorators accepteren drie argumenten.
- Het prototype van de klasse
- De naam van de methode
- Parameterindex
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.
In dit voorbeeld wordt de LogParameter
decorator toegepast op de eerste parameter van de greet
methode, en wanneer de methode wordt aangeroepen, wordt gelogd dat de parameter is gedecoreerd.
Praktische voorbeelden van decorators
Decorators worden veel gebruikt in frameworks zoals Angular, vooral voor dependency injection en metadatadefinitie. Gebruik bijvoorbeeld de @Component
decorator om Angular-componenten zoals hieronder te definiëren.
1@Component({
2 selector: 'app-root',
3 template: '<h1>Hello World</h1>',
4})
5export class AppComponent {}
Decorators worden dus vaak gebruikt als kernonderdelen van frameworks en bibliotheken, waardoor code beknopt en duidelijk blijft.
Samenvatting van decorators
TypeScript decorators zijn krachtige hulpmiddelen die flexibel functionaliteit toevoegen aan klassen, methoden en eigenschappen. Het gebruik van aangepaste decorators verbetert de onderhoudbaarheid en herbruikbaarheid van de code en maakt verdere abstractie mogelijk. Decorators spelen een belangrijke rol in frameworks zoals Angular en NestJS, en ze begrijpen helpt om diepgaand te begrijpen hoe deze frameworks werken.
Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.