- vừa được xem lúc

Decorator trong TypeScript

0 0 13

Người đăng: Anthony Tran

Theo Viblo Asia

Trong bài viết này, chúng ta sẽ tìm hiểu về Decorator trong TypeScript, một tính năng mạnh mẽ giúp mở rộng và thay đổi hành vi của các class, method, property và parameter. Decorator giúp làm cho code trở nên dễ đọc và dễ bảo trì hơn. Hãy cùng khám phá cách sử dụng và những lợi ích mà Decorator mang lại.

1. Decorator là gì?

Decorator là một function đặc biệt được dùng để thay đổi hoặc mở rộng hành vi của class, method, property hoặc parameter trong TypeScript. Decorator cho phép chúng ta thêm chức năng mới mà không cần sửa đổi code ban đầu của đối tượng.

2. Decorator và Lập trình hướng khía cạnh (AOP)

Decorator trong TypeScript có mối liên hệ nhất định với lập trình hướng khía cạnh (Aspect-Oriented Programming - AOP). AOP là một mô hình lập trình nhằm mục đích tách biệt các mối quan tâm xuyên suốt (cross-cutting concerns) khỏi logic chính của ứng dụng. Những mối quan tâm này thường bao gồm logging, bảo mật, xử lý ngoại lệ, và các nhiệm vụ phụ trợ khác.

Trong AOP, có một số khái niệm chính như Aspect (module chứa logic phụ trợ), Join Point (điểm trong quá trình thực thi nơi một aspect có thể áp dụng), Advice (đoạn code được thực thi tại một join point) và Pointcut (biểu thức định nghĩa join points mà một aspect sẽ áp dụng). Decorator trong TypeScript có thể được coi là một biểu hiện cụ thể của các khái niệm này, khi chúng cho phép chúng ta thêm hoặc thay đổi hành vi của các class, method, property hoặc parameter mà không cần sửa đổi code ban đầu.

3. Decorator và Decorator Design Pattern

Decorator trong TypeScript cũng liên quan đến Decorator Design Pattern. Cả hai đều được sử dụng để thay đổi hoặc mở rộng hành vi của đối tượng, nhưng được áp dụng trong các ngữ cảnh khác nhau.

Decorator Design Pattern là một design pattern cho phép thêm hành vi cho các đối tượng mà không ảnh hưởng đến các đối tượng khác cùng class. Design pattern này thường được triển khai bằng composition.

Ví dụ về Decorator Design Pattern:

interface Component { operation(): string;
} class ConcreteComponent implements Component { operation(): string { return 'ConcreteComponent'; }
} class Decorator implements Component { protected component: Component; constructor(component: Component) { this.component = component; } operation(): string { return this.component.operation(); }
} class ConcreteDecoratorA extends Decorator { operation(): string { return `ConcreteDecoratorA(${super.operation()})`; }
} class ConcreteDecoratorB extends Decorator { operation(): string { return `ConcreteDecoratorB(${super.operation()})`; }
} const simple = new ConcreteComponent();
console.log(simple.operation()); const decoratedA = new ConcreteDecoratorA(simple);
console.log(decoratedA.operation()); const decoratedB = new ConcreteDecoratorB(decoratedA);
console.log(decoratedB.operation());

TypeScript Decorators là một tính năng ngôn ngữ cho phép thêm annotation và metadata vào các class và members. Chúng được sử dụng để thay đổi hành vi của các class, method, property hoặc parameter.

Ví dụ về Decorator trong TypeScript:

function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype);
} @sealed
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return `Hello, ${this.greeting}`; }
}

4. Cách khai báo Decorator

Trong TypeScript, Decorator được khai báo bằng cách sử dụng ký hiệu @ theo sau là tên của hàm decorator. Có bốn loại decorator chính:

  1. Class Decorator: Áp dụng cho các class.
  2. Method Decorator: Áp dụng cho các method của class.
  3. Property Decorator: Áp dụng cho các property của class.
  4. Parameter Decorator: Áp dụng cho các parameter của method trong class.

5. Ví dụ về Decorator

Class Decorator

Class Decorator được sử dụng để thêm hoặc thay đổi hành vi của một class. Dưới đây là một ví dụ về Class Decorator:

function sealed(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype);
} @sealed
class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return `Hello, ${this.greeting}`; }
}

Trong ví dụ trên, decorator @sealed sẽ khóa class Greeter và ngăn không cho thêm hoặc xóa các property và method của nó.

Method Decorator

Method Decorator được sử dụng để thay đổi hành vi của một method. Dưới đây là ví dụ về Method Decorator:

function enumerable(value: boolean) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { descriptor.enumerable = value; };
} class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } @enumerable(false) greet() { return `Hello, ${this.greeting}`; }
}

Trong ví dụ trên, decorator @enumerable(false) sẽ làm cho method greet không liệt kê được (non-enumerable).

Property Decorator

Property Decorator được sử dụng để thay đổi hành vi của một property. Dưới đây là ví dụ về Property Decorator:

function logProperty(target: any, key: string) { let _val = target[key]; const getter = () => { console.log(`Get: ${key} => ${_val}`); return _val; }; const setter = (newVal) => { console.log(`Set: ${key} => ${newVal}`); _val = newVal; }; Object.defineProperty(target, key, { get: getter, set: setter, enumerable: true, configurable: true });
} class Greeter { @logProperty greeting: string; constructor(message: string) { this.greeting = message; } greet() { return `Hello, ${this.greeting}`; }
}

Trong ví dụ trên, decorator @logProperty sẽ ghi log mỗi khi property greeting được truy cập hoặc thay đổi.

Parameter Decorator

Parameter Decorator được sử dụng để thay đổi hành vi của một parameter trong method. Dưới đây là ví dụ về Parameter Decorator:

function logParameter(target: any, key: string, index: number) { const metadataKey = `__log_${key}_parameters`; if (Array.isArray(target[metadataKey])) { target[metadataKey].push(index); } else { target[metadataKey] = [index]; }
} class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet(@logParameter message: string) { return `Hello, ${message}`; }
}

Trong ví dụ trên, decorator @logParameter sẽ ghi log chỉ số của parameter khi method greet được gọi.

6. Ứng dụng của Decorator trong TypeScript

Decorator trong TypeScript đã được sử dụng rộng rãi trong nhiều framework và thư viện nổi tiếng như Angular, NestJS, TypeORM, và nhiều công cụ khác.

  • Angular: Sử dụng decorators để định nghĩa các thành phần, dịch vụ và các yếu tố khác của ứng dụng.

    @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css']
    })
    export class AppComponent { title = 'my-app';
    }
    
  • NestJS: Sử dụng decorators để định nghĩa các controller, service và module trong ứng dụng.

    @Controller('cats')
    export class CatsController { @Get() findAll(): string { return 'This action returns all cats'; }
    }
    
  • TypeORM: Sử dụng decorators để định nghĩa các entity và mối quan hệ giữa chúng.

    @Entity()
    export class User { @PrimaryGeneratedColumn() id: number; @Column() firstName: string; @Column() lastName: string;
    }
    

7. Kết luận

Decorators trong TypeScript là một công cụ mạnh mẽ giúp mở rộng và thay đổi hành vi của class, method, property và parameter mà không cần phải sửa đổi code ban đầu. Việc sử dụng decorators giúp cho code trở nên rõ ràng hơn và dễ bảo trì hơn. Thêm vào đó, chúng có liên quan mật thiết đến các khái niệm trong lập trình hướng khía cạnh (AOP) và Decorator Design Pattern, giúp tách biệt các mối quan tâm xuyên suốt ra khỏi logic chính của ứng dụng. Hy vọng qua bài viết này, bạn đã hiểu thêm về decorators và cách sử dụng chúng trong TypeScript.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 528

- vừa được xem lúc

Type annotation vs Type Inference - Typescript

Trong bài viết này, chúng ta sẽ tìm hiểu kỹ về TypeScript bằng cách tìm hiểu sự khác biệt giữa kiểu chú thích và kiểu suy luận. Tôi sẽ cho rằng bạn có một số kinh nghiệm về JavaScript và biết về các kiểu cơ bản, như chuỗi, số và boolean.

0 0 45

- vừa được xem lúc

Type Annotation và Type Inference trong TypeScript là gì?

Khi làm việc với javascript chắc hẳn các bạn đã quá quen với việc dùng biến mà không cần phải quan tâm đến kiểu dữ liệu của nó là gì phải không? Đúng là mới đầu tiếp cận với Typescript mình cũng cảm thấy nó khá là phiền vì cần phải khai báo đủ type để nó chặt chẽ hơn. Lúc đó mình còn nghĩ: " JavaScr

0 0 37

- vừa được xem lúc

Tìm hiểu TypeScript và kiến thức cơ bản

TypeScript là gì. TypeScript sử dụng tất cả các tính năng của của ECMAScript 2015 (ES6) như classes, modules.

0 0 53

- vừa được xem lúc

TypeScript - P1: Vì sao TypeScript được yêu thích đến vậy?

Trải nghiệm thực tế. Trước khi là một Web Developer, tôi là một Mobile Developer và Java là thứ mà tôi từng theo đuổi.

0 1 69

- vừa được xem lúc

4 Tính năng rất hay từ TypeScript

Xin chào các bạn hôm nay mình xin chia sẽ những tính năng rất hay của TypeScript (TS), các bạn cùng tìm hiểu nhé. Ngoài việc set Type cho biến, tham số hay function thì ví dụ khi bạn nhìn vào một tham

0 0 96