Created
November 13, 2016 15:50
-
-
Save thatseeyou/4573714b21fe9f181381886f21b8e6b0 to your computer and use it in GitHub Desktop.
TypeScript 2.0 Decorators example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// npm i reflect-metadata --save | |
//import "reflect-metadata"; | |
import "core-js" // Using Symbol for ES5 target | |
@sealed | |
class Greeter { | |
@propertyDecorator | |
private _greeting: string; | |
constructor(message: string) { | |
this._greeting = message; | |
} | |
@methodTrace(true) | |
greet(msg: string) { | |
return `Hello, ${this._greeting} : ${msg}`; | |
} | |
@methodTrace(false) | |
@validate | |
greet2(msg: string, @required msg2: string) { | |
return `Hi, ${this._greeting} : ${msg} - ${msg2}`; | |
} | |
@methodTrace(true) | |
get greeting() { | |
return this._greeting; | |
} | |
set greeting(newValue) { | |
this._greeting = newValue; | |
} | |
} | |
let a: Greeter = new Greeter('World'); | |
a.greeting = 'Universe'; | |
console.log(a.greeting); | |
console.log(a.greet('It\'s me')); | |
console.log(a.greet2('It\'s me', undefined)); | |
function sealed(constructor: Function) { | |
Object.seal(constructor); | |
Object.seal(constructor.prototype); | |
} | |
function methodTrace(debug: boolean) { | |
console.log('Call methodTraceDecoratorFactory'); | |
if (debug) { | |
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { | |
console.log('Call methodTraceDecorator'); | |
console.log(` target = ${target}, propertyKey = ${propertyKey}, descriptor = ${descriptor}`); | |
for (let key of ['get', 'set', 'value']) { | |
if (descriptor[key]) { | |
let origFunc = descriptor[key]; | |
descriptor[key] = makeLogMethod(origFunc); | |
} | |
} | |
return descriptor; | |
function makeLogMethod(origFunc: Function) { | |
return function logMethod(this: Object, ...args: any[]) { | |
let result = origFunc.apply(this, args); | |
let a = args.map(a => JSON.stringify(a)).join(); | |
let r = JSON.stringify(result); | |
console.log(`Call: ${propertyKey}(${a}) => ${r}`); | |
return result; | |
} | |
} | |
} | |
} | |
else { | |
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { | |
console.log('Call methodTraceDecorator -> No Return'); | |
console.log(` target = ${target}, propertyKey = ${propertyKey}, descriptor = ${descriptor}`); | |
} | |
} | |
} | |
function propertyDecorator(target: any, propertyKey: string) { | |
console.log('Call propertyDecorator'); | |
console.log(` target = ${target}, propertyKey = ${propertyKey}`); | |
//console.log(target); | |
} | |
const requiredMetadataKey = Symbol("required"); | |
function required(target: Object, propertyKey: string | symbol, parameterIndex: number) { | |
console.log('Call required'); | |
console.log(` target = ${target}, propertyKey = ${propertyKey}, parameterIndex = ${parameterIndex}`); | |
let existingRequiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || []; | |
existingRequiredParameters.push(parameterIndex); | |
Reflect.defineMetadata(requiredMetadataKey, existingRequiredParameters, target, propertyKey); | |
} | |
function validate(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<Function>) { | |
console.log('Call validate'); | |
console.log(` target = ${target}, propertyName = ${propertyName}, descriptor = ${descriptor}`); | |
let method = descriptor.value; | |
descriptor.value = function (this:Object) { | |
let requiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyName); | |
if (requiredParameters) { | |
for (let parameterIndex of requiredParameters) { | |
if (parameterIndex >= arguments.length || arguments[parameterIndex] === undefined) { | |
throw new Error("Missing required argument."); | |
} | |
} | |
} | |
return method.apply(this, arguments); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment