export const PROP_METADATA = '__prop__metadata__' ; function makeMetadataCtor ( props ? ) { return function ctor ( ... args ) { if ( props ) { const values = props ( ... args ) ; for ( const propName in values ) { this [ propName ] = values [ propName ] ; } } } ; } export function makePropDecorator ( _name , props ? ) { const metaCtor = makeMetadataCtor ( props ) ; function PropDecoratorFactory ( ... args ) { if ( this instanceof PropDecoratorFactory ) { metaCtor . apply ( this , args ) ; return this ; } const decoratorInstance = new ( < any > PropDecoratorFactory ) ( ... args ) ; return function PropDecorator ( target , name ) { const constructor = target . constructor ; const meta = constructor . hasOwnProperty ( PROP_METADATA ) ? ( constructor as any ) [ PROP_METADATA ] : Object . defineProperty ( constructor , PROP_METADATA , { value : { } } ) [ PROP_METADATA ] ; meta [ name ] = meta . hasOwnProperty ( name ) && meta [ name ] || [ ] ; meta [ name ] . unshift ( decoratorInstance ) ; } ; } PropDecoratorFactory . prototype . metadataName = _name ; return PropDecoratorFactory ; }