// Class decorator function seal(constructor: Function) { Object.seal(constructor); Object.seal(constructor.prototype); } // Method decorator function setTimeout(ms = 0) { // Notice the wrapper function to get arguments, this can be done to any decorator function return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function () { setTimeout(() => originalMethod.apply(this, arguments), ms); }; return descriptor; } } // Accessor/Property decorator function log(target: any, key: string) { let value = target[key]; Object.defineProperty(target, key, { get: () => { console.log(`Get => ${key}`); return value; }, set: (newValue) => { console.log(`Set: ${key} => ${e}`); value = newValue; }, enumerable: true, configurable: true }); } // Example @seal class Person { @log firstName: string; @log lastName: string; @log get name() { return `${this.firstName} ${this.lastName}`}; constructor(firstName: string, lastName: string) { this.firstName = firstName; this.lastName = lastName; } @timeout(1000) whoami() { return this.name; } }