Search code examples
javascriptannotationsbabeljs

In Javascript, is it possible to access a field's annotated data at run time?


Given the example JavaScript code :

function foo = key => target => {
  target.key = key;

  return target;
}

class Bob {

  @foo('hello')
  a = 'world';

}

const bob = new Bob();

Is there a way to access the value of key from the annotated field at run-time? Something like :

getAnnotationTarget(bob, 'a').key;  // "hello"

The point of this question is to allow class field annotation, and retrieving data associated with that field from the annotation. The field's value itself should not be affected, i.e. bob.a = "blah"; should not affect the annotation value associated with the field.

My naive thought was to extend the field's prototype from the annotation, but it seems unavailable when the annotation is executed.

Thank you.


Solution

  • You could add a (hidden) Map to the class, then look that up:

     const hidden = Symbol();
    
     decorator @foo(value) {
       @register((target, prop) => {
          if(!target[hidden]) target[hidden] = new Map();
          target[hidden].set(prop, value);
        }
     }
    
     const getAnnotationTarget = (instance, key) =>
        instance.constructor[hidden].get(key);
    

    Or using the babel proposal syntax the decorator looks like:

     const foo = (value) => (target, prop) => {
        target = target.constructor;
        if(!target[hidden]) target[hidden] = new Map();
        target[hidden].set(prop, value);
    
     };