1

Getting a function name is pretty straightforward:

const func1 = function() {}

const object = {
  func2: function() {}
}

console.log(func1.name);
// expected output: "func1"

console.log(object.func2.name);
// expected output: "func2"

How can I get the string name of a getter/setter, though?

class Example {
  get hello() {
    return 'world';
  }
}

const obj = new Example();

Important note:

I don't want to use a hard-coded string:

Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), 'hello')

But get the name, e.g.:

console.log(getGetterName(obj.hello))
// expected output: "hello"
15
  • 1
    My question is obviously NOT a duplicate, as I don't want to access the getter by string name but to GET its string representation. Commented Jan 13, 2020 at 16:29
  • 1
    @NicholasTower I think typescript is actually important here and the idea is that the construction is type-safe. Commented Jan 13, 2020 at 16:34
  • 1
    stackblitz.com/edit/… Commented Jan 13, 2020 at 16:37
  • 1
    You can't. Properties created with get or set are considered "Pseudo" properties. You must know the string name of the prop to use it, and it is undiscoverable. So the others saying "you can find the hello" prop are correct - but you have to know hello. Commented Jan 13, 2020 at 16:41
  • 1
    Please, please, please, clarify your question!! Not in the comments, actually edit your question so it reflects your true intent! Commented Jan 13, 2020 at 16:56

1 Answer 1

2

That syntax sets the get function of the hello property descriptor so the name of the function will always be get you can check if the hello property has a get function on it's property descriptor with Object.getOwnPropertyDescriptor().

class Example {
  get hello() {
    return 'world';
  }
}
/*
compiles to / runs as
var Example = (function () {
    function Example() {
    }
    Object.defineProperty(Example.prototype, "hello", {
        get: function () {
            return 'world';
        },
        enumerable: true,
        configurable: true
    });
    return Example;
}());
*/

const des = Object.getOwnPropertyDescriptor(Example.prototype, 'hello');
console.log(des.get.name); // get (will always be 'get')

// to check if 'hello' is a getter
function isGetter(name) {
  const des = Object.getOwnPropertyDescriptor(Example.prototype, name);
  return !!des && !!des.get && typeof des.get === 'function';
}
console.log(isGetter('hello')); // true

Sounds like this won't solve your ultimate issue but: Object.getOwnPropertyDescriptor(Example.prototype, 'hello').get.name 100% answers the question "How to get getter/setter name in JavaScript/TypeScript?" and it will always be "get"

Edit:
Once you call obj.hello the getter is already called an all you have is the primitive result, but you may be able to use metadata on the property value its self.

function stringPropertyName() {
  let _internal;
  return (target, key) => {
    Object.defineProperty(target, key, {
      get: () => {
        const newString = new String(_internal);
        Reflect.defineMetadata('name', key, newString);
        return newString;
      },
      set: value => {
        _internal = value;
      }
    });
  };
}

class Example1 {
  @stringPropertyName()
  hello = 'world';
}

const obj1 = new Example1();
console.log(Reflect.getMetadata('name', obj1.hello)); // hello

class Example2 {
  _hello = 'world';
  get hello() {
    const newString = new String(this._hello);
    Reflect.defineMetadata('name', 'hello', newString);
    return newString;
  }
  set hello(value) {
    this._hello = value;
  }
}

const obj2 = new Example2();
console.log(Reflect.getMetadata('name', obj2.hello)); // hello
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.11/core.min.js"></script>

Sign up to request clarification or add additional context in comments.

5 Comments

No, it does not answer the question. All your code does is create a getter for a Pseudo property named 'hello' and then using the string hello simply returns the property name that you just set, namely the string hello. The question should be clarified, but the real question is "how does one reflect the property name created with a setter or getter without using the property name to find it?". That cannot be done.
I don't see "how does one reflect the property name created with a setter or getter without using the property name to find it?" anywhere in the original question. Also you say "All your code does is create a getter for a Pseudo property named 'hello' " but that is straight from the original question.
The OP has edited the question to clarify that the OP specifically does not want to do what your answer suggests the OP do.
And I added an "Edit" section in response
I removed my downvote in favor of benefit of the doubt. The true, real answer is - you can't do what the OP wants to do - it is undiscoverable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.