If you have worked in Java universe with Spring frameworks (or others like lombok), you would be familiar with power of annotations.
Put a @RestMapping
annotation on a method! Bam! It's exposed as an API.
Put a @Data
annotation on a class! Bam! You have all the verbose methods like getters
, setters
, toString
and much more.
Decorators works in a similar way for TypeScript. These 2 enable us to abstract out redundant and non business related codes like caching, logging, validity of parameters and a lot more.
What are Decorators in Typescript
From TypeScriptLang
A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. Decorators use the form @expression, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.
Why to use Decorators
- Abstract out redundant code
- Keep business logic clean
- Boost developer productivity
- Keep Non-functional things like caching/logging/validations standardise across services
Look at this basic example
const getUsernameById(String userId) {
const userName = CACHE.get("bucket", userId);
if(!_.isNil(userName)) {
return userName;
}
const user = UserModel.getById(userId);
CACHE.set("bucket", userId, user.name);
Log.info(
method: "getUsernameById"
key_1: "userId",
key_1_value: userId,
key_2: "userName",
key_2_value: userName
)
return user.name;
}
Using decorators, it can be reduced to
@Cacheable
@Loggable
const getUsernameById(String userId){
const user = UserModel.getById(userId);
return user.name;
}
PS: These implementations/naming can be different for others, but gist is same
What all entity Decorators can support
Just like Java, typescript support class method/function and property level decorators and many more:
- Class decorators: Can be used for creating components or singleton objects.
- Method decorators: Can be used for logging request response of a method, caching params and returned value, etc
- Property decorators: Can be used for validating a property value on assignment or initialisation A detailed description can be found here.
How can I start with Decorators for my project
Trust me when I say this, it's very easy to implement. It'll be one of those projects which will give you the highest ROI on engineering investments. It took me few hours to implement @Cache
and @Log
for a test project. The working project can be found here.
What's next
To create an npm library which out of the box will support these annotations just like spring-boot. Do give a pull request if you have any suggestions.
Top comments (2)
Decorators have always frustrated me because they’re limited only to classes.
You can’t decorate a function declaration, or a variable. And I cannot see any genuine reason why not, other than “we copied decorators from X OOP language”
Bring decorators to FP please!
Bring decorators to FP please! => Agree
Till then, it's definitely helpful and powerful for the folks who're using OOP with TS!!