How can I get a variables name in typescript? I want something like this:
var name = "Foo";
alert(getVariableName(name)); //Prints "name"
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));
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).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"
Object.keys({ name })[0].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.
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.
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.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
//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
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.
nameoffunction: ts-nameof. You can use it with parts of the language only available in TypeScript too (ex. interfaces and type aliases).