title: Metadata Proposal - ECMAScript status: proposal location: https://rbuckton.github.io/reflect-metadata copyright: false contributors: Ron Buckton
Proposal to add Metadata to ECMAScript.
    // define metadata on an object or property
    Reflect.defineMetadata(metadataKey, metadataValue, target);
    Reflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);
    // check for presence of a metadata key on the prototype chain of an object or property
    let result = Reflect.hasMetadata(metadataKey, target);
    let result = Reflect.hasMetadata(metadataKey, target, propertyKey);
    // check for presence of an own metadata key of an object or property
    let result = Reflect.hasOwnMetadata(metadataKey, target);
    let result = Reflect.hasOwnMetadata(metadataKey, target, propertyKey);
    // get metadata value of a metadata key on the prototype chain of an object or property
    let result = Reflect.getMetadata(metadataKey, target);
    let result = Reflect.getMetadata(metadataKey, target, propertyKey);
    // get metadata value of an own metadata key of an object or property
    let result = Reflect.getOwnMetadata(metadataKey, target);
    let result = Reflect.getOwnMetadata(metadataKey, target, propertyKey);
    // get all metadata keys on the prototype chain of an object or property
    let result = Reflect.getMetadataKeys(target);
    let result = Reflect.getMetadataKeys(target, propertyKey);
    // get all own metadata keys of an object or property
    let result = Reflect.getOwnMetadataKeys(target);
    let result = Reflect.getOwnMetadataKeys(target, propertyKey);
    // delete metadata from an object or property
    let result = Reflect.deleteMetadata(metadataKey, target);
    let result = Reflect.deleteMetadata(metadataKey, target, propertyKey);
    // apply metadata via a decorator to a constructor
    @Reflect.metadata(metadataKey, metadataValue)
    class C {
      // apply metadata via a decorator to a method (property)
      @Reflect.metadata(metadataKey, metadataValue)
      method() {
      }
    }
    // Design-time type annotations
    function Type(type) { return Reflect.metadata("design:type", type); }
    function ParamTypes(...types) { return Reflect.metadata("design:paramtypes", types); }
    function ReturnType(type) { return Reflect.metadata("design:returntype", type); }
    // Decorator application
    @ParamTypes(String, Number)
    class C {
      constructor(text, i) {
      }
      @Type(String)
      get name() { return "text"; }
      @Type(Function)
      @ParamTypes(Number, Number)
      @ReturnType(Number)
      add(x, y) {
        return x + y;
      }
    }
    // Metadata introspection
    let obj = new C("a", 1);
    let paramTypes = Reflect.getMetadata("design:paramtypes", inst, "add"); // [Number, Number]
  When the abstract operation GetOrCreateMetadataMap is called with Object _O_, property key _P_, and Boolean _Create_ the following steps are taken:
All ordinary objects have an internal slot called [[Metadata]]. The value of this internal slot is either *null* or a *Map* object and is used for storing metadata for an object.
When the [[HasMetadata]] internal method of _O_ is called with ECMAScript language value _MetadataKey_ and property key _P_, the following steps are taken:
When the abstract operation OrdinaryHasMetadata is called with ECMAScript language value _MetadataKey_, Object _O_, and property key _P_, the following steps are taken:
When the [[HasOwnMetadata]] internal method of _O_ is called with ECMAScript language value _MetadataKey_ and property key _P_, the following steps are taken:
When the abstract operation OrdinaryHasOwnMetadata is called with ECMAScript language value _MetadataKey_, Object _O_, and property key _P_, the following steps are taken:
When the [[GetMatadata]] internal method of _O_ is called with ECMAScript language value _MetadataKey_ and property key _P_, the following steps are taken:
When the abstract operation OrdinaryGetMetadata is called with ECMAScript language value _MetadataKey_, Object _O_, and property key _P_, the following steps are taken:
When the [[GetOwnMetadata]] internal method of _O_ is called with ECMAScript language value _MetadataKey_ and property key _P_, the following steps are taken:
When the abstract operation OrdinaryGetOwnMetadata is called with ECMAScript language value _MetadataKey_, Object _O_, and property key _P_, the following steps are taken:
When the [[DefineOwnMetadata]] internal method of _O_ is called with ECMAScript language value _MetadataKey_, ECMAScript language value _MetadataValue_, and property key _P_, the following steps are taken:
When the abstract operation OrdinaryDefineOwnProperty is called with ECMAScript language value _MetadataKey_, ECMAScript language value _MetadataValue_, Object _O_, and property key _P_, the following steps are taken:
When the [[MetadataKeys]] internal method of _O_ is called with property key _P_ the following steps are taken:
When the abstract operation OrdinaryMetadataKeys is called with Object _O_ and property key _P_ the following steps are taken:
When the [[OwnMetadataKeys]] internal method of _O_ is called with property key _P_ the following steps are taken:
When the abstract operation OrdinaryOwnMetadataKeys is called with Object _O_ and property key _P_ the following steps are taken:
When the [[DeleteMetadata]] internal method of _O_ is called with ECMAScript language value _MetadataKey_ and property key _P_ the following steps are taken:
This section contains amendments to the Reflect object.
A metadata decorator function is an anonymous built-in function that has [[MetadataKey]] and [[MetadataValue]] internal slots.
When a metadata decorator function _F_ is called with arguments _target_ and _key_, the following steps are taken:
When the `metadata` function is called with arguments _metadataKey_ and _metadataValue_, the following steps are taken:
When the `defineMetadata` function is called with arguments _metadataKey_, _metadataValue_, _target_, and _propertyKey_, the following steps are taken:
When the `hasMetadata` function is called with arguments _metadataKey_, _target_, and _propertyKey_, the following steps are taken:
When the `hasOwnMetadata` function is called with arguments _metadataKey_, _target_, and _propertyKey_, the following steps are taken:
When the `getMetadata` function is called with arguments _metadataKey_, _target_, and _propertyKey_, the following steps are taken:
When the `getOwnMetadata` function is called with arguments _metadataKey_, _target_, and _propertyKey_, the following steps are taken:
When the `getMetadataKeys` function is called with arguments _target_ and _propertyKey_, the following steps are taken:
When the `getOwnMetadataKeys` function is called with arguments _target_ and _propertyKey_, the following steps are taken:
When the `deleteMetadata` function is called with arguments _metadataKey_, _target_, and _propertyKey_, the following steps are taken: