Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get method name from within a typescript method

I want to get the name of the current method from within an instance method of a class in Typescript.

(Pseudocode, doesn't work):

class Foo {
    bar() {
        console.log(something); //what should something be?
    }
}

new Foo().bar();

I expect 'something' to return 'bar'. I realize that this can give me the class, and I could somehow get the class and its attributes from it, but I do not know how to get 'this function' (i.e, the method bar, not the class Foo).

I have seen several other questions related to finding the class name, etc. but not one that addresses getting the current method name.

like image 449
Anand Avatar asked Aug 17 '17 20:08

Anand


People also ask

What is a name function in JavaScript& how to define it?

Named Functions: In JavaScript, named functions are simply a way of referring to a function that employs the function keyword followed by a name that can be used as a callback to that function. Normal functions with a name or identifier are known as named functions.

How do I find the class of an object in TypeScript?

Use the name property on an object's constructor to get the class name of the object, e.g. const className = e1.constructor.name . The constructor property returns a reference to the constructor function that created the object.

Can function name and variable name be same in JavaScript?

What is it you would expect? Variables and functions share the same namespace in JavaScript, so they override each other. if function name and variable name are same then JS Engine ignores the variable.

How to give return Type in TypeScript?

To define the return type for the function, we have to use the ':' symbol just after the parameter of the function and before the body of the function in TypeScript. The function body's return value should match with the function return type; otherwise, we will have a compile-time error in our code.


2 Answers

Besides the arguments.callee.name there is no straightforward way of getting this.

I propose 2 other methods:

Use decorators to inject the method name:

function annotateName(target, name, desc) {
    var method = desc.value;
    desc.value = function () {
        var prevMethod = this.currentMethod;
        this.currentMethod = name;
        method.apply(this, arguments);
        this.currentMethod = prevMethod;   
    }
}

class Foo {
    currentMethod: string;

    @annotateName
    bar() {
        alert(this.currentMethod);
        this.tux();
        alert(this.currentMethod);
    }

    @annotateName
    tux() {
        alert(this.currentMethod);
    }
}

new Foo().bar();

The downside is that you have to annotate all the functions you want to get the name from. You could instead just annotate the class and in the decorator you would iterate over all prototype functions and apply the same idea.


My second option is not standardised and need more care to get consistent results across browsers. It relies on creating an Error object and getting it's stack trace.

class Foo {
    bar() {
        console.log(getMethodName());    
    }
}

function getMethodName() {
    var err = new Error();
    return /at \w+\.(\w+)/.exec(err.stack.split('\n')[2])[1] // we want the 2nd method in the call stack

}

new Foo().bar();
like image 194
Cristi Mihai Avatar answered Oct 14 '22 09:10

Cristi Mihai


Not sure if this would help, but:

class Foo {
    bar() {
        console.log(Object.getOwnPropertyNames(Foo.prototype)); // ["constructor", "bar"]
    }
}

new Foo().bar();
like image 3
Slai Avatar answered Oct 14 '22 08:10

Slai