Table of contents
Exploring TypeScript Decorators
Frontend
Frontend
TypeScript, a statically typed superset of JavaScript, is a modern-age programming language that offers a wide array of advanced features. One of these features is decorators, a concept that greatly extends your ability to modify classes, properties, and methods. This post aims to shed light on the concept of TypeScript decorators, with detailed examples and explanations.
Note: To enable experimental support for decorators, you must enable the experimentalDecorators compiler option either on the command line or in your tsconfig.json.
Command Line
Note: To enable experimental support for decorators, you must enable the experimentalDecorators compiler option either on the command line or in your tsconfig.json.
Command Line
// language: bash tsc --target ES5 --experimentalDecorators
tsconfig.json
// language: javascript { "compilerOptions": { "target": "ES5", "experimentalDecorators": true } }
1. What is decorator?
Decorators are a design pattern in TypeScript, offering a way to add both annotations and a meta-programming syntax for class declarations and members. They can be used to modify or encapsulate behaviors of methods, classes, properties or parameters, without changing their source code.
Decorators use the form @expression, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.
Decorators use the form @expression, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.
For example, given the decorator @log we might write the sealed function as follows:
// language: javascript function log(target) { // do something with 'target' }
If we want to customize how a decorator is applied to a declaration, we can write a decorator factory. A Decorator Factory is simply a function that returns the expression that will be called by the decorator at runtime.
We can write a decorator factory in the following fashion:
// language: javascript function log(mode: string) { return function (target) { // do something with 'target' and 'mode'... } }
2. Class Decorators
Class decorators in TypeScript are applied to the constructor of the class and can be used to observe, modify, or replace a class definition. These decorators are called with one parameter, which is the constructor of the decorated class.
Here's the general syntax for a class decorator:
Here's the general syntax for a class decorator:
// language: javascript function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) { return class extends constructor { // new behavior } }
Example 1:
// language: javascript function circleDecorator<T extends { new (...args: any[]): {} }>(constructor: T) { return class extends constructor { lower_bound = 0; pi = 3.14; } } @circleDecorator class MathTool { lower_bound: number; upper_bound = 100; constructor() { this.lower_bound = -100; } } console.log(new MathTool()); // { lower_bound: 0, upper_bound: 100, pi: 3.14 }
In this example, the circleDecorator function replaces the original MathTool with a new class that extends MathTool, adding a pi and overriding the lower_bound property. When a new instance of MathTool is created, it contains the modifications made by the decorator.
Example 2:
// language: javascript function logCreation<T extends { new (...args: any[]): {} }>(constructor: T) { return class extends constructor { constructor(...args: any[]) { super(...args); console.log(`Instance of ${constructor.name} created`); } } } @logCreation class Character { name: string; constructor(name: string) { this.name = name; } } @logCreation class Enemy { type: string; constructor(type: string) { this.type = type; } } const character = new Character("John") // "Instance of Character created" const enemy = new Enemy("Dragon") // "Instance of Enemy created"
3. Method Decorators
Method decorators in TypeScript are a powerful and flexible feature that can be used to observe, modify, or replace a method definition. They're declared just before a method declaration. The decorator is applied to the Property Descriptor for the method and can be used to observe, modify, or replace a method definition.
A method decorator is expressed as a function that will be called at runtime with three arguments:
- Either the constructor function of the class for a static member, or the prototype of the class for an instance member.
- The name of the member.
- The Property Descriptor for the member.
// language: javascript function methodDecorator<T>( target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T> ) { // your decorator logic }
Here's an example of a method decorator usage:
// language: javascript function deprecated(target: any, propertyKey: string, descriptor: PropertyDescriptor) { console.log(`${propertyKey} has been deprecated`); descriptor.value = function() { return 999; } } class MathTool { @deprecated sum() { return 100; } } let myInstance = new MathTool(); console.log(myInstance.sum()); // "sum has been deprecated" // 999
In the above example, the @deprecated decorator replaces the original sum with a new function that indicates the method has been deprecated. The original functionality of sum is lost, replaced by the new function.
Method decorators provide an elegant way to add behavior to methods or change their behavior entirely. They allow for cleaner, more organized, and modular code, enhancing the overall development experience with TypeScript.
Created at
2024-04-03 22:56:46 +0700
Related blogs
[PART 1] Unlocking React Interview: Key Questions and In-Depth Answers
React.js is one of the most popular JavaScript libraries for building user interfaces. Whether you're a seasoned developer or just starting out, under...
Frontend
Frontend
2024-06-17 21:16:52 +0700
[PART 1] Unlocking JavaScript Interview: Promises and Timers
JavaScript interviews often include questions about asynchronous programming, as it's a fundamental concept in modern web development. One common chal...
Frontend
Frontend
2024-06-23 16:51:19 +0700