33

How can I get a variables name in typescript? I want something like this:

var name = "Foo";
alert(getVariableName(name)); //Prints "name"
2
  • I've created a library that adds a nameof function: ts-nameof. You can use it with parts of the language only available in TypeScript too (ex. interfaces and type aliases). Commented Sep 17, 2016 at 21:31
  • Does this answer your question? Variable name as a string in Javascript Commented Nov 22, 2021 at 21:07

7 Answers 7

23

Expanding on basarat's answer, you need to create function that takes as a parameter a function that will contain the access to your variable. Because in JavaScript you can access the code of any function it then becomes a simple matter of using a regex to extract the variable name.

var varExtractor = new RegExp("return (.*);");
export function getVariableName<TResult>(name: () => TResult) {
    var m = varExtractor.exec(name + "");
    if (m == null) throw new Error("The function does not contain a statement matching 'return variableName;'");
    return m[1];
}

var foo = "";
console.log(getVariableName(() => foo));
Sign up to request clarification or add additional context in comments.

4 Comments

If I'm not mistaken, for properties of objects this will return the class qualified name, for example: Foo.bar. To return only the property name, it might be feasible to return only the part of name after the last dot, using m[1].substring(Math.max(0, m[1].lastIndexOf("."))). The Math.max call is used to handle the case when lastIndexOf would return -1, in which case the entire string should be returned (from index 0).
Some minifications do not remove ";" from function body so it is safer to use new RegExp("return (.*)}"); and then replace ";" with empty string and trim it.
I've added a variation that allows for the full path to be retrieved. mrpmorris.blogspot.co.uk/2017/08/…
@PeterMorris the original question was regarding a variable name, which wouldn't be qualified by anything else. Your code will get the property (or property path) that is accessed on the parameter. Which is also a very useful function, just the answer to a different question :)
9

One approach is to store such values in an object:

var o = {
    firstName: "Homer",
    lastName: "Simpson"
};

We can't get the name of o, but we can get the names (or "keys") of its two properties:

var k = Object.keys(o);
console.log(k[0]); // prints "firstName"

1 Comment

If you don't have an object or don't want to create a named object the same could be expressed as Object.keys({ name })[0].
5

Expanding Cernicova-Dragomir's answer:

Expanding on basarat's answer, you need to create function that takes as a parameter a function that will contain the access to your variable. Because in JavaScript you can access the code of any function it then becomes a simple matter of using a regex to extract the variable name.

to also support a field of an object:

var varExtractor = new RegExp("(.*)");

export function getVariableName<TResult>(getVar: () => TResult) {
    var m = varExtractor.exec(getVar + "");

    if (m == null)
        throw new Error("The function does not contain a statement matching 'return variableName;'");

    var fullMemberName = m[1];
    var memberParts = fullMemberName.split('.');

    return memberParts[memberParts.length-1];
}

var foo = { bar: "" };
var varName = getVariableName(() => foo.bar ); //prints "bar"

Notice that I've deleted the "return" because it doesn't work on Node.js when targeting ES6.

Comments

4

TypeScript is JavaScript at runtime. So the same limitations as there apply : Get the 'name' of a variable in Javascript

However you can do stuff like

alert(getVariableName(()=>name)) 

Here you would parse the body of the function passed into getVariableName and get that as a string.

1 Comment

However, TypeScript is compiled into JavaScript, so in theory it could support a nameof(varibleName) operator that will work during compilation time. I wonder why they didn't do it already. This is one of the benefits of having a compilation process, and TS should take full advantage of it.
2

Look at my answer for JavaScript migrated to TypeScript:

const nameOf = (f: () => void) => (f).toString().replace(/[ |()=>]/g, '');

Examples:

nameOf(() => myVariable)             // myVariable
nameOf(() => myVariable.name)        // myVariable.name
nameOf(() => myVariable.name.length) // myVariable.name.length
nameOf(() => myVariable.name[10])    // myVariable.name[10]
nameOf(() => MySuperClass)           // MySuperClass

Comments

1
//typescript
function getVarName(obj: object): string {
  const keys = Object.keys(obj);
  console.assert(keys.length == 1, 'key count must be 1');
  return keys[0];
}
const simpleName = 123;
console.log(getVarName({ simpleName }), simpleName);

or

//javascript
"use strict";
function getVarName(obj) {
    const keys = Object.keys(obj);
    console.assert(keys.length == 1, 'key count must be 1');
    return keys[0];
}
const simpleName = 123;
console.log(getVarName({ simpleName }), simpleName);

it will output

[LOG]: simpleName, 123

but i think it should be finished in compile duration will be better in instead of runtime

Comments

1

If the variable is part of a class/interface, there is a really simple solution:

function getFieldName<T, K extends keyof T = keyof T>(name: K): K {
    return name;
}

I.e. const name = getFieldName<SomeInterface>('some_field') provides a compile-time guarantee that name contains 'some_field', and some_field is a valid field of SomeInterface.

Comments

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.