Get method name from within a typescript method

前端 未结 5 1082
陌清茗
陌清茗 2021-01-04 07:33

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 {
    ba         


        
相关标签:
5条回答
  • 2021-01-04 07:44

    Not sure if this would help, but:

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

    0 讨论(0)
  • 2021-01-04 07:46

    Just to answer the question with another interesting take, you could do (but shouldn't do) something like this:

    class Foo {
        constructor(private http: HttpClient) {
    
            const apiUrl = 'http://myapi.com/api/';
    
            {
                const functionName = 'getBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
    
            {
                const functionName = 'postBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
    
            {
                const functionName= 'putBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
    
            {
                const functionName= 'deleteBar';
                this[functionName] = function () {
                    return http.get(apiUrl + functionName);
                }
            }
        }
    }
    

    It certainly is not an elegant solution, and I can't really imagine a good use case for doing something like this, as I'm pretty sure the compiler doesn't recognize new Foo(http).deleteBar(). Maybe someone can come up with an elegant solution with this idea, I'll leave that as an experiment for someone.

    But with this pattern (if you employ some kind of devops scaffolding or "strong copy-paste skills") you can always access your method's name via functionName

    0 讨论(0)
  • 2021-01-04 07:47

    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();
    
    0 讨论(0)
  • 2021-01-04 07:49

    Keep in mind that during compilation and minification you might lose the actual name of what you're trying to use. You might consider looking into the ts-nameof babel macro that reads the name of virtually anything during compilation and returns it's actual string representation.

    0 讨论(0)
  • 2021-01-04 08:08

    for class name - Foo.name for method name - this.bar.name

    0 讨论(0)
提交回复
热议问题