Skip to main content

How Decorators Have Changed In TypeScript Version 5

ยท 4 min read

I wrote an article explaining what are decorators and the article was written in context of version 4.x of TypeScript. In this article, we are going to talk about how decorators have changed in version 5.0 of TypeScript.

Why Is There A Change In Decorators ๐Ÿค”โ€‹

For those who have been working with TypeScript for some time, it is likely that you are already familiar with the presence of "experimental" decorators in the language for several years. Decorators are an upcoming ECMAScript feature that allow us to customize classes and their members in a reusable way.

TypeScript Course Instructor Image
TypeScript Course Instructor Image

Time To Transition From JavaScript To TypeScript

Level Up Your TypeScript And Object Oriented Programming Skills. The only complete TypeScript course on the marketplace you building TypeScript apps like a PRO.

SEE COURSE DETAILS

Comparing Version 4.x And 5.x Of TypeScript ๐Ÿค“โ€‹

Since decorators are an upcoming ECMAScript feature that allow us to customize classes and their members in a reusable way. TypeScript has brought in changes to how Decorators work in version 5.0 and that is to bridge the gap between the current experimental decorators and the proposed ECMAScript decorators. In this section we will compare how class decorators work differently in version 4.x and 5.x of TypeScript.

Version 4.xโ€‹

Here's a simple example of a class decorator in TypeScript version 4.x:

function LogClass(target: any) {
console.log(`Class ${target.name} has been decorated.`);
}

@LogClass
class MyClass {
// Class implementation
}

Version 5.xโ€‹

If you use the same Decorator in TypeScript version 5.x, you will get an error because decorators in version 5.x need some required parameters.

function LogClass(originalClass: any, _context: ClassDecoratorContext) {
console.log(_context);
console.log(originalClass);
}

@LogClass
class MyClass {
// Class implementation
constructor(private name: string) {}

public printName() {
return `My name is ${this.name}`;
}
}

This TypeScript code demonstrates the use of a decorator, LogClass, which is a higher-order function that takes another class as an argument and adds additional behavior to it. Decorators are a way to modify or extend the behavior of classes or class members.

Let's break down the code:

  1. LogClass function: This is the decorator function. It accepts two arguments, originalClass and _context. originalClass is the class that the decorator will be applied to, and _context is passed by default as the second argument to the decorator function. _context is an object that contains metadata about the decorator.

  2. MyClass: This is a simple class with a constructor and a printName method. The constructor takes a single argument, name, which is a private property of the class.

  3. @LogClass: This is the decorator syntax, which applies the LogClass decorator to the MyClass class. When the decorator is applied, it will call the LogClass function with MyClass as the first argument, and _context is an object that will contain metadata about the decorator.

Decorator Factories ๐Ÿญโ€‹

Decorator factories in TypeScript are functions that return a decorator. They are used when you need to customize or configure a decorator with specific arguments or options before applying it to a class, method, property, or parameter.

By using a decorator factory, you can create more flexible and reusable decorators that can be configured with different settings for different use cases. The decorator factory is invoked with the desired configuration and returns the actual decorator function, which can then be applied to the target.

Decorator Factories Version 5.xโ€‹

function LogClassFactory(lastName: string) {
return function LogClass(originalClass: any, _context: any) {
console.log(_context);
console.log(originalClass);
console.log(lastName);
};
}

@LogClassFactory("Doe")
class MyClass {
// Class implementation
constructor(private name: string) {}

@LogMethod
public printName() {
return `My name is ${this.name}`;
}
}

What Can You Do Next ๐Ÿ™๐Ÿ˜Šโ€‹

If you liked the article, consider subscribing to Cloudaffle, my YouTube Channel, where I keep posting in-depth tutorials and all edutainment stuff for ssoftware developers.

YouTube @cloudaffle