Decorators trong TypeScript
Decorators là một công cụ rất hữu ích khi viết các ứng dụng bằng Typescript. Nếu bạn đã từng làm việc các ngôn ngữ hay framework như C#, Java hay APS.NET MVC sẽ thấy quen thuộc với cú pháp decorators này. Ví dụ chúng được sử dụng trong các ứng dụng web với mô hình MVC là dùng để cấu hình routing cho ứng dụng. Đi kèm theo đó, trong quá trình phát triển, sẽ có nhiều trường hợp mà ta thấy cần phải thêm thông tin hoặc chỉnh sửa các class hoặc thành phần của class (property, method …), đặc biệt ở run-time. Lúc này, Decorators, Metadata Reflection xuất hiện và cung cấp các phương thức cho phép ta thêm vào các chú thích hoặc meta-data cho class, property, method …
Decorator có thể coi như một cú pháp khai báo đặc biệt, không bao giờ đứng độc lập mà luôn được gắn kèm với một khai báo class, method, property hoặc accessor, được viết dưới cú pháp dạng @expression, với expression trỏ tới một function sẽ được gọi tới ở runtime, có nhiệm vụ thay đổi hoặc bổ sung cho đối tượng được decorate.
Trong TS có 5 loại decorator
* class decorator
* method decorator
* property decorator
* accessor decorator
* parameter decorator
Class decorator: được khai báo trước khi khai báo class ngay bên trên và nó apply cho contructor của class để sử dụng, chỉnh sửa or thay thế định nghĩa của class.
Ví dụ:
@sealed class Student {}
Tương ứng với nó, decorator function sẽ nhận 1 param – constructor của class được decorate. Ví dụ:
@sealed class Student { stdName: string; constructor(message: string) { this.stdName = message; } greet() { return "Hello, " + this.stdName; } } function sealed(constructor: Function) { console.log(Object.seal(constructor)); console.log(Object.seal(constructor.prototype)); }
decorator trên sẽ log ra mỗi khi có 1 instance mới của class được khởi tạo.
console.log(new Student("Alice"));
Method decorator
Method decorator được khai báo với 3 params:
– Target: class chứa method đó
– Tên member được decorate (chính là tên method)
– Property descriptor
Ví dụ:
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } @enumerable(false) greet() { return "Hello, " + this.greeting; } } function enumerable(value: boolean) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { descriptor.enumerable = value; }; }
@enumerable(false) ở đây là một method decorator, khi decorator @enumerable(false) được gọi, nó sữa sửa đổi thuộc tính enumerable của descriptor.
Accessor decorator
Tương tự với 2 decorator trên, accessor decorator dùng để decorate cho accessor của 1 property nào đó, tuy nhiên chúng ta chỉ định nghĩa decorate với accessor nào (get or set ) được viết trước tiên.
Ví dụ dưới đây là 1 accessor decorator được áp dụng cho 1 member của Demo class :
class Demo { private _name: string; @modify get name(): string { return `My name is ${this._name}`; } }
// ở đây ko cần viết @modify nữa
set name(input: string): void {
}
Parameter decorator
Decorator loại này được định nghĩa ngay trước 1 parameter – có thể là 1 param của 1 function hoặc của constructor của Class.
Parameter decorator nhận đầu vào là 3 params
* class đầu vào.
* tên của param được decorate.
* thứ tự của param trong list các params của function cha.
Parameter decorator chỉ được sử dụng để kiểm tra sự tồn tại của params trong function , và thường được dùng kết hợp với method decorator hoặc accessor decorator
Ví dụ:
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } @validate greet(@required name: string) { return "Hello " + name + ", " + this.greeting; } }
Tài liệu tham khảo:
– https://www.typescriptlang.org/docs/handbook/decorators.html