Reputation: 6769
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"
Upvotes: 1
Views: 1619
Reputation: 3043
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>
Upvotes: 2