The class decorator takes the constructor function as a parameter, allows us to change the way how this class is initialized.
Let's say we have a couple of classes Customer
and Order
. It is required that every class needs to have created
property.
The normal solution is to create a base class which will have common fields and allow the childern to inherit from this.
In this example, we will use decorator to achieve this behavior, the decorator function will receive the target's constructor function as a parameter, and add the created
property to its prototype
.
Here is the code for decorator:
function EntityWithTimeStamp(constructorFunction: Function) { constructorFunction.prototype.created = new Date().toLocaleString("en-US"); console.log("decorator called"); }
It receives constructorFunction
(of the target class) as parameter, and adds created
property to its prototype
.
The decorator is ready to be used in each entity. We only need to add @EntityWithTimeStamp
before class definition.
Here we define our classes and adds @EntityWithTimeStamp
decorator.
@EntityWithTimeStamp class Customer { constructor(public name: string) { console.log("Customer controctor called"); } } @EntityWithTimeStamp class Order { constructor(public amount: number) { console.log("Order controctor called"); } }
Both of these classes have defined their own public properties received in constructor. Also they will have an additional property created
which will be added by the decorator.
You can create objects of these classes as usual, and output the public properties to console:
let customer = new Customer("Idrees"); let order = new Order(100); console.log(order.amount); console.log(customer.name);
Note that the decorator does not change the TypeScript type and the new property created
is not known to the type system. The following lines will give you the error because compiler will not find created
property in these referenced classes/types:
console.log(order.created); console.log(customer.created);
Error message:
error TS2339: Property 'created' does not exist on type 'Customer'. error TS2339: Property 'created' does not exist on type 'Order'.
There is a work around this issue, you can access the created
property by temporarily casting the object to type any
.
console.log((<any>order).created); console.log((<any>customer).created);
Output will display the value of crearted
property, which shows that decorator has added this field as the class member.