Obtain the name of a method within a typescript function

Is there a way to retrieve the name of the current method within an instance method of a class in Typescript?

(Pseudocode, it's not functional):

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

new Foo().bar();

I'm looking for 'something' to return 'bar'. I know that this can provide me with the class, and I could potentially extract the class and its properties from it, but I am uncertain on how to access 'this function' (specifically, the method bar rather than the class Foo).

I have come across multiple questions regarding determining the class name, etc. however none seem to address retrieving the current method name.

Answer №1

Besides using arguments.callee.name, there is no direct method to achieve this.

I present two alternative approaches:

1. Implement decorators to include 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 drawback here is that you need to add annotations for each function where you want to retrieve the name. Alternatively, you could implement a decorator at the class level and iterate over all prototype functions in the decorator.


2. Another option involves creating an Error object and extracting its stack trace, although it may not yield consistent results across different browsers due to lack of standardization:

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

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

}

new Foo().bar();

Answer №2

My solution for determining the method name is outlined below.

  /**
   * @summary Function to retrieve the caller's name
   * @returns {string} The name of the invoker
   */
  private static getCallerName(): string {
    try {
      throw new Error();
    } catch (e) {
      try {
        return e.stack.split('at ')[3].split(' ')[0];
      } catch (e) {
        return '';
      }
    }
  }

Answer №3

Here is a potential solution:

function SomeFunction() {
    console.log("Hello world!");
}

SomeFunction();

Answer №4

It's important to remember that when compiling and minifying your code, you could potentially lose the original names of variables or functions. One solution is to explore using the ts-nameof Babel macro, which can extract the actual name of almost anything during compilation and provide its string representation.

Answer №5

While searching for a resolution, I stumbled upon this helpful snippet:

class Widget {
  display() {
      console.log(this.display.name); // <-- Show the method name.
  }
}
  
new Widget().display(); 

An interesting aspect is that an error will be triggered if the function name is modified without updating the corresponding console output.

Answer №6

use Foo.name for the class name and this.bar.name for the method name.

Answer №7

To provide a different perspective on this question, consider the following unconventional approach:

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);
            }
        }
    }
}

This method is not elegant and it's hard to find a practical use case for such implementation. The compiler may not recognize new Foo(http).deleteBar(), making it even more challenging. Perhaps someone can devise a more refined solution based on this concept as an experimental challenge.

Despite its drawbacks, this pattern allows you to access the method names using functionName if combined with devops scaffolding or strong copy-paste skills.

Answer №8


function retrieveCallerFunctionName() {
   return retrieveCallerFunctionName.caller.name
}

function displayCallerName() {
  console.log(retrieveCallerFunctionName())
}

displayCallerName() // logs the name of the caller function

To access the calling function, use the .caller property:

The .caller property of a Function object allows you to reference the function that called the current function. Keep in mind that for strict mode, async functions, and generator functions, using the caller property will result in an exception being thrown.

Although not a standardized feature, I have found the .caller property to be widely supported in my usage (primarily in node.js). Prior to implementation, always verify compatibility. I typically utilize this property for debugging purposes. For further details, refer to

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller

Answer №9

It seems like this question has been circulating for quite some time, so I wanted to share my own take on it.

function getMethodName(): string {
  const stackRegex = /at (\w+|new)[\.|\s]?(\w+|<anonymous>)/gi;

  const position = 2;

  const stackTrace = (new Error().stack || '').split('\n');
  if (stackTrace.length <= position) {
    return 'ERROR: unknown';
  }

  const currentStack = stackTrace[position];
  const methodMatch = stackRegex.exec(currentStack);

  if (!methodMatch || methodMatch.length < 3) return `FIXME: ${currentStack}`;

  switch (methodMatch[1]) {
    case 'Object':
      return '<node.js>'; // Represents "run_main" of Node.JS

    case 'new': // Handle constructors differently
    default:
      return methodMatch[2];
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Switch the URL of the current tab to a different one by clicking a button within a Chrome extension with the help of JavaScript

Could someone assist me in changing the current tab URL to a different website, such as , using a chrome extension? Here is my JavaScript code: chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { var tab = tabs[0]; console.log(tab.url) ...

The issue with AngularJS ng-show and $timeout functionality not functioning as expected

As a newcomer to AngularJS, I recently started an individual project utilizing ng-show and if else statements with $timeout. Despite my efforts, I have been unable to make the answers timeout after being displayed for a few seconds. I've tried various ...

What is the best way to group by date only from an ISODate field in a Node.js application?

const reportSchema = new Schema({ session_id: {type: Schema.Types.ObjectId, ref: 'Session'}, learner_id: {type: Schema.Types.ObjectId, ref: 'User'}, text: {type: String}, }); Report.aggregate( [ ...

Transform a string format of an array into a JavaScript array

I have a challenge with converting a legacy database that currently stores user roles as a string in the following format: ["ADMIN", "MANAGER", "USER"] My goal is to convert this string into an array within the response I send from Express. This is what ...

What is the best way to verify the relationship between parent and children nodes in a tree structure?

Check out my Plnkr with nested loops of checkboxes: here Below is the HTML code for the nested loops of checkboxes: <ul> <li ng-repeat="continent in destinations"> <input type="checkbox" ng-model="continent.selected"> {{contin ...

When links are hovered over, the cursor hand does not vanish even when using the style code "cursor: none;"

Currently, I am attempting to customize my cursor so that it only changes when hovering over links. Instead of setting cursor: none for the entire body, I am working on removing the default hand cursor using JavaScript. Despite the inspector showing that ...

What causes my page to refresh every time I click on a blank link?

I have a link that looks like this: <a hreflang="15" class="comment-show-link" href="">View/hide comments</a> Afterwards, I use the following code to toggle the visibility of the content: $('.comment-show-link').click(function(e) { ...

Instructions for setting a default value for ng-options when dealing with nested JSON data in AngularJS

I need help setting a default value for my ng-options using ng-init and ng-model with dependent dropdowns. Here is an example of my code: <select id="country" ng-model="statessource" ng-disabled="!type2" ng-options="country for (country, states) in c ...

Developing a counter/timer feature in a web application using PHP and MySQL

I am currently working on a form that submits data to a database with the possibility of the issue being either 'resolved' or 'notresolved'. My goal is to create a timer that starts counting as soon as the form is submitted and the issu ...

How can I turn off warnings for angular-translation?

A series of translation related warnings are appearing in the browser console, and I am looking to suppress or disable all of these warnings to prevent them from being shown to the user. Warnings: Translation for Department doesn't exist a.(anonymous ...

Ember's route-refreshing event

Exploring the possibility of displaying a modal when a specific route is refreshed in an ember app. The modal will offer an 'ok' action to proceed with the refresh and a 'cancel' action to stop it. Although Ember has a 'refresh()& ...

What is the impact on socket IDs when a Node.js server undergoes a restart?

For my multiplayer game powered by Node.js and socket.io, I have successfully implemented game rooms where players can join different rooms. This part is working well. However, in order to prepare for the possibility of a server crash, I have set up Node ...

Creating a dynamic effect to blur slideshow content located underneath a specific div

Struggling to figure out how to achieve a blur effect on a slideshow with moving elements? Most resources focus on static images, but I need help with objects in motion. My project involves a jQuery Cycle slideshow, and I want the background areas of over ...

I am experiencing a strange situation in node.js where the `then` condition of a Promise is not being executed as expected

I am currently troubleshooting a Promise scenario and I am puzzled as to why the second then condition is failing to execute in the setup method. In my app.js code, I can see that the initialize() function is being called and it properly awaits the complet ...

Executing two distinct SQL queries within one nodejs function

I'm facing an issue with updating two tables in my database - the stockmaster table and the prodstock table. I've been trying to run a query using a function to update both tables simultaneously, but unfortunately, it's not working as expect ...

Adding a method to an object with TypeScript: A step-by-step guide

In my current scenario, I am faced with a challenge where I need to test a function with a specific use of this. However, typescript poses constraints by either disallowing me from adding the method to the object, or if I define it as any, then my interfac ...

Tips for transferring contact information from a webpage to an Android or iPhone using an HTML button and integrating JavaScript or PHP

My current project involves adding a feature to a website that allows users to save contact details from the site to their phone (Android or iPhone) with the click of an HTML button. Here's what I have done so far <!DOCTYPE html> <html lang= ...

When using Nuxt JS and Jest, a warning message may appear stating "[Vue warn]: Invalid Component definition" when importing an SVG file

I am facing a unique issue only in my Jest unit test where an error occurs when I import an SVG into the component being tested: console.error node_modules/vue/dist/vue.common.dev.js:630 [Vue warn]: Invalid Component definition: found in -- ...

What measures can I take to ensure TypeScript transpiles prototype methods effectively?

Having some issues defining methods on a TypeScript class and then accessing them. Even though the methods are defined, it's giving an error that they don't exist. TypeScript: export class ColumnHeader extends JSONObject { // ... i ...

Securing your Node.js connect-rest REST API with OAuth: A comprehensive guide

After conducting an extensive search on Google for examples related to my query, I was left empty-handed due to the generic name of the "connect-rest" package. My objective is to secure a server side API that I have built using the Node module "connect-re ...