Reflect.js
function decorate(decorators, target, propertyKey, attributes) {
            if (!IsUndefined(propertyKey)) {
                if (!IsArray(decorators))
                    throw new TypeError();
                if (!IsObject(target))
                    throw new TypeError();
                if (!IsObject(attributes) && !IsUndefined(attributes) && !IsNull(attributes))
                    throw new TypeError();
                if (IsNull(attributes))
                    attributes = undefined;
                propertyKey = ToPropertyKey(propertyKey);
                return DecorateProperty(decorators, target, propertyKey, attributes);
            }
            else {
                if (!IsArray(decorators))
                    throw new TypeError();
                if (!IsConstructor(target))
                    throw new TypeError();
                return DecorateConstructor(decorators, target);
            }
        }
function decorate(decorators, target, propertyKey, attributes) {
            if (!IsUndefined(propertyKey)) {
                if (!IsArray(decorators))
                    throw new TypeError();
                if (!IsObject(target))
                    throw new TypeError();
                if (!IsObject(attributes) && !IsUndefined(attributes) && !IsNull(attributes))
                    throw new TypeError();
                if (IsNull(attributes))
                    attributes = undefined;
                propertyKey = ToPropertyKey(propertyKey);
                return DecorateProperty(decorators, target, propertyKey, attributes);
            }
            else {
                if (!IsArray(decorators))
                    throw new TypeError();
                if (!IsConstructor(target))
                    throw new TypeError();
                return DecorateConstructor(decorators, target);
            }
        }
Applies a set of decorators to a property of a target object.
@param decorators An array of decorators.
@param target The target object.
@param propertyKey (Optional) The property key to decorate.
@param attributes (Optional) The property descriptor for the target key.
@remarks Decorators are applied in reverse order.
@example

class Example {
// property declarations are not part of ES6, though they are valid in TypeScript:
// static staticProperty;
// property;

constructor(p) { }
static staticMethod(p) { }
method(p) { }
}

// constructor
Example = Reflect.decorate(decoratorsArray, Example);

// property (on constructor)
Reflect.decorate(decoratorsArray, Example, "staticProperty");

// property (on prototype)
Reflect.decorate(decoratorsArray, Example.prototype, "property");

// method (on constructor)
Object.defineProperty(Example, "staticMethod",
Reflect.decorate(decoratorsArray, Example, "staticMethod",
Object.getOwnPropertyDescriptor(Example, "staticMethod")));

// method (on prototype)
Object.defineProperty(Example.prototype, "method",
Reflect.decorate(decoratorsArray, Example.prototype, "method",
Object.getOwnPropertyDescriptor(Example.prototype, "method")));