Reflect.js
function metadata(metadataKey, metadataValue) {
            function decorator(target, propertyKey) {
                if (!IsObject(target))
                    throw new TypeError();
                if (!IsUndefined(propertyKey) && !IsPropertyKey(propertyKey))
                    throw new TypeError();
                OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey);
            }
            return decorator;
        }
function metadata(metadataKey, metadataValue) {
            function decorator(target, propertyKey) {
                if (!IsObject(target))
                    throw new TypeError();
                if (!IsUndefined(propertyKey) && !IsPropertyKey(propertyKey))
                    throw new TypeError();
                OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey);
            }
            return decorator;
        }
4.1.2 Reflect.metadata(metadataKey, metadataValue) https://rbuckton.github.io/reflect-metadata/#reflect.metadata 
A default metadata decorator factory that can be used on a class, class member, or parameter.
@param metadataKey The key for the metadata entry.
@param metadataValue The value for the metadata entry.
@returns A decorator function.
@remarks
If `metadataKey` is already defined for the target and target key, the
metadataValue for that key will be overwritten.
@example

// constructor
@Reflect.metadata(key, value)
class Example {
}

// property (on constructor, TypeScript only)
class Example {
@Reflect.metadata(key, value)
static staticProperty;
}

// property (on prototype, TypeScript only)
class Example {
@Reflect.metadata(key, value)
property;
}

// method (on constructor)
class Example {
@Reflect.metadata(key, value)
static staticMethod() { }
}

// method (on prototype)
class Example {
@Reflect.metadata(key, value)
method() { }
}