Typescript Decorators in Examples

Artem Diashkin
Nov 21, 2020 · 7 min read
Image for post
Image for post

Let’s take a look at the Typescript Decorators that provide a way to add both annotations and a meta-programming syntax for class declarations and members.

⚠️ NOTE Decorators are an experimental feature that may change in future releases.

What will be covered in this article:

  1. Prerequisites
  2. What is Decorator
  3. Simple examples
  4. Decorators in depth

1. Prerequisites

Before we start exploring Typescript Decorator examples, I’ll be using an empty Node.js typescript project with no additional packages, lints, etc.

All we will need is a typescript in our dev dependencies in the package.json file:

First, create an empty folder:

Image for post
Image for post

Next, initialize npm project by running npm init -y in the root dir of your empty project: (-y flag means that you are answering yes to all npm questions)

Image for post
Image for post

Next, we will need to add typescript npm package to our dev dependencies:

yarn add typescript -D
Image for post
Image for post

Next, we will need to add tsconfig.json file by running npx tsc — init in the root of our project:

Image for post
Image for post

⚠️NOTE: To enable experimental support for decorators, you must enable the experimentalDecorators compiler option either on the command line or in your tsconfig.json file:

Before we will start creating TS Decorators we will need a test subject → I will create a example/User.ts file that will contain a simple User class:

Image for post
Image for post

Now we are ready to create our first decorators 👍

2. What is Decorator

“Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members. Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript.”

So what are those Decorators, really? As you can see from the gist below it is a function that returns a function of a specific Type:

  • ClassDecorator
  • PropertyDecorator
  • MethodDecorator
  • ParameterDecorator

In the next simple examples, we will not cover those return functions and their input parameters, so you could get the main idea behind Decorators first, and after that, we will discuss those params in-depth, be patient 😉

3. Simple examples

So, before we will dive deep into the input parameters of each Decorator let’s take a look at some simple examples…

Class Decorator

We will start with the Class Decorator:

Image for post
Image for post

Let’s run this file and see what will happen.

For run use command:

npx ts-node examples/User.ts
Image for post
Image for post

⚠️ NOTE: If you are working in WebStorm IDE you create a custom configuration for running your active files. You can check more about it here:

Property Decorator

Property decorators are primarily used to create and attach metadata (it will be covered in the next section 4. Decorators in depth).

Now, let’s create a simple PropertyDecorator:

Image for post
Image for post

Result:

Image for post
Image for post

Method Decorator

Next, create MethodDecorator:

Image for post
Image for post

Result:

Image for post
Image for post

Parameter Decorator

Add last but not least — simple Parameter Decorator:

Image for post
Image for post

Result:

Image for post
Image for post

Multiple Decorators

The awesome thing about all Decorators is that you can put them on top of each other. Method Decorators even allow you to chain return data and modify it:

Image for post
Image for post

And see the result:

Image for post
Image for post

4. Decorators in depth

Now we can take a closer look at the Decorators return functions and their input params. What additional features do they provide?

Class Decorator

ClassDecorator return function type has only one input parameter → target :

By using it you can manipulate with the target’s prototype (we can add an additional field if we want) or we can even create a new instance of the target class:

Image for post
Image for post

… for fixing ts-ignore we can use this annotation:

(user as User & { isOld: boolean }).isOld

Result:

Image for post
Image for post

Property Decorator

Property Decorators are mostly used for adding Metadata.

For our demo purposes, we will need to add reflect-metadata npm package to our project’s dev dependencies:

yarn add reflect-metadata -D

For metadata we will use Symbol data type, if are not familiar whit that data type — you can check more about it here:

Before we will start coding let me show you what we will get as a result:

Image for post
Image for post

Result:

Image for post
Image for post

Now let’s see how we can achieve that…

I will remove all previous Decorators and clean-up User class so we could focus on Property Decorator only:

addReflectMetadata function looks like this:

If you are not familiar with the reflect-metadata and how it works under the hood → I will leave console output so you could get the main idea:

Image for post
Image for post

Method Decorator

Before a theory tour, I will show you what we can get as a result.

What will be the result of 2+2?

Nope 🙂:

Image for post
Image for post

MethodDecorator is a little bit trickier. The main difficulty can occur when you will face TypedPropertyDescriptor<T> . Let’s spend some time on a theory:

To make our life easier, and Typescript happier we will use PropertyDescriptor type for the descriptor param instead.

⚠️ NOTE: This article is not about Generics and TS Type Guards, but don't use this approach (TypedPropertyDescriptor<T>PropertyDescriptor) in production, unless you are totally sure.

  • target: The prototype of the class;
  • propertyKey: The name of the method;
  • descriptor: A TypedPropertyDescriptor<T> → (We will use PropertyDescriptor instead), if you are not familiar with this type you can read about it here:

… but I will show you a quick example of how it works:

Result:

Image for post
Image for post

Now, let’s create our method decorator:

…and wrap our “calculate” function with it:

Image for post
Image for post

Result:

Image for post
Image for post

..and last but not least…

Parameter Decorator

Parameter Decorators are mostly used for adding Metadata exactly the same as Property Decorators used.

I think that after MethorDecorator and PropertyDecorator you get the main idea behind the ParemeterDecorator an how could work without any examples 😉, but I wanted to show you an example from the official docs:

Result of this code fragment:

Image for post
Image for post
Image for post
Image for post

Now you are totally ready for creating your own Decorators. 🎉 Happy coding!

Source code:

The Startup

Medium's largest active publication, followed by +771K people. Follow to join our community.

Artem Diashkin

Written by

Java, Spring, Node.js, AdonisJs, React.js and Flutter developer

The Startup

Medium's largest active publication, followed by +771K people. Follow to join our community.

Artem Diashkin

Written by

Java, Spring, Node.js, AdonisJs, React.js and Flutter developer

The Startup

Medium's largest active publication, followed by +771K people. Follow to join our community.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store