TypeScript Decorators - Sprinkle Some Magic on Your Code
FSMD Fahid Sarker
Senior Software Engineer · June 21, 2024
TypeScript Decorators: A Comprehensive Guide
Ah, TypeScript decorators—the secret sauce that can make your code look like a finely-ground symphony of functionality. Or spaghetti. Truly, it's a coin flip. But worry not, dear reader! By the end of this comprehensive guide, you’ll be tossing around decorators like a seasoned artisan.
What Are Decorators?
Decorators are a special kind of declaration that can be attached to a class, method, accessor, property, or parameter. They’re basically JavaScript functions that add annotations and a bit of meta-programming syntax for class declarations and members.
Think of decorators as the chocolate sprinkles on your vanilla sundae. They don’t change the sundae itself but add that extra flair which makes you go, "Oh la la!"
Types of Decorators
- Class Decorators
- Method Decorators
- Accessor Decorators
- Property Decorators
- Parameter Decorators
In this artisanal guide, we’re going to make each of these decorators as digestible as a grandma’s homemade apple pie.
Class Decorators
Class decorators are applied to the class constructor and can be used to modify the class or replace it entirely.
Code.typescriptfunction AnimalDecorator(constructor: Function) { console.log(`ClassDecorator was called on:`, constructor); } @AnimalDecorator class Animal { constructor(public name: string) {} }
- Console Output:
ClassDecorator was called on: class Animal { constructor(name) { this.name = name; } }
If only my dog’s bark was as elegant as this decorator’s output!
Method Decorators
Method decorators are applied to the methods of the class, and they get three arguments: the target, the method name, and the property descriptor.
Code.typescriptfunction Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args: any[]) { console.log(`Calling ${propertyKey} with arguments`, args); return originalMethod.apply(this, args); }; } class Calculator { @Log add(a: number, b: number) { return a + b; } } const calc = new Calculator(); calc.add(2, 3); // Console Output: Calling add with arguments [2, 3]
Accessor Decorators
Accessor decorators are similar to method decorators but are used for class accessors (getters and setters).
Code.typescriptfunction ReadOnly( target: any, propertyKey: string, descriptor: PropertyDescriptor ) { descriptor.writable = false; } class Person { private _name: string; constructor(name: string) { this._name = name; } @ReadOnly get name(): string { return this._name; } }
Your accessors are like fine wine, making your code aged to perfection.
Property Decorators
Property decorators are applied to the properties of the class. They do not receive a PropertyDescriptor.
Code.typescriptfunction DefaultGreeting(target: any, propertyKey: string) { target[propertyKey] = "Hello, World!"; } class Greeter { @DefaultGreeting greeting: string; } const greeter = new Greeter(); console.log(greeter.greeting); // Console Output: "Hello, World!"
Instantly feel the warm embrace of default values, like a comforting blanket.
Parameter Decorators
Parameter decorators are as rare as a unicorn in a parking lot. These are used to annotate parameters within a function.
Code.typescriptfunction LogParameter( target: any, propertyKey: string, parameterIndex: number ) { const existingRequiredParameters: number[] = Reflect.getOwnMetadata("logParameters", target, propertyKey) || []; existingRequiredParameters.push(parameterIndex); Reflect.defineMetadata( "logParameters", existingRequiredParameters, target, propertyKey ); } class Transaction { deposit(@LogParameter amount: number) { console.log(`Depositing ${amount}`); } } const t = new Transaction(); t.deposit(100); // No extra logging here; see below for the full usage.
Use parameter decorators wisely; they’re like the secret spices in grandma’s apple pie recipe—special but should be used sparingly!
Wrapping Up
Phew! There you go, a whirlwind tour through the land of TypeScript decorators. With great power comes great responsibility, so use these decorators judiciously!
Decorators add a touch of magic to your code, making it more expressive and powerful. Until next time, may your code be bug-free and your decorators as charming as ever.
Now go forth, and sprinkle these tasty TypeScript treats into your project!
Happy Coding! 🍰
PS: If you enjoyed this guide, give it a ⭐ on GitHub—or send me cookies. I like cookies.