Skip to content

Instantly share code, notes, and snippets.

@frontdevops
Created January 22, 2016 14:03
Show Gist options
  • Save frontdevops/0196eb8e8f315d0b7d72 to your computer and use it in GitHub Desktop.
Save frontdevops/0196eb8e8f315d0b7d72 to your computer and use it in GitHub Desktop.
TypeScript decorators example
//"use strict";
function logProperty(target:Object, key:string):void {
var val:any = this[key];
const getter = function():any {
console.log(`Get: ${key} => ${val}`);
return val;
};
const setter = function (newVal):void {
console.log(`Set: ${key} => ${newVal}`);
val = newVal;
};
if (delete this[key])
Object.defineProperty(target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
function logParameter(target:Object, key:string, index:number) {
var metadataKey = `log_${key}_parameters`;
if (Array.isArray(target[metadataKey])) {
target[metadataKey].push(index);
}
else {
target[metadataKey] = [index];
}
}
function logMethod(target:any, key:string, descriptor:any) {
var originalMethod = descriptor.value;
descriptor.value = function (...args:any[]) {
var indices = target[`__log_${key}_parameters`];
if (Array.isArray(indices)) {
for (let i = 0; i < args.length; i++) {
if (indices.indexOf(i) !== -1) {
let arg = args[i];
let argStr = JSON.stringify(arg) || arg.toString();
console.log(`${key} arg[${i}]: ${argStr}`);
}
}
return originalMethod.apply(this, args);
}
let a = args.map(a => (JSON.stringify(a) || a.toString())).join();
let result = originalMethod.apply(this, args);
let cln = target.constructor.name;
console.log(`Call: ${cln}.${key}(${a}) => ${JSON.stringify(result)}`);
return result;
};
return descriptor;
}
function logClass(target:Object):Object {
var original = target;
function construct(constructor, args) {
let c:any = function(){
return constructor.apply(this, args);
};
c.prototype = constructor.prototype;
return new c;
}
let f:any = (...args) => {
console.log(`New: ${original.name}`);
return construct(original, args);
};
f.prototype = original.prototype;
return f;
}
function log(...args : any[]):any {
args = args.filter(n=>n!=undefined);
switch(args.length) {
case 1: return logClass.apply(this, args);
case 2: return logProperty.apply(this, args);
case 3:
if(typeof args[2] === "number")
return logParameter.apply(this, args);
return logMethod.apply(this, args);
default: throw new Error("Decorators are not valid here!");
}
}
@log
class Person {
@log public name:string;
@log public surname:string;
constructor(name:string, surname:string) {
this.name = name;
this.surname = surname;
}
@log
public say(@log message:string):string {
return `${this.name} ${this.surname} says: ${message}`;
}
}
let me = new Person("Alex", "Mayorov");
let you = new Person("Kira", "Hagakyre");
me.say('Hi, Kira!');
you.say('Hi, Alex!');
/* Output:
New: Person
Set: name => Alex
Set: surname => Mayorov
New: Person
Set: name => Kira
Set: surname => Hagakyre
Get: name => Kira
Get: surname => Hagakyre
Call: Person.say("Hi, Kira!") => "Kira Hagakyre says: Hi, Kira!"
Get: name => Kira
Get: surname => Hagakyre
Call: Person.say("Hi, Alex!") => "Kira Hagakyre says: Hi, Alex!"
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment