1

Is it possible in Javascript/Typescript to write a function that returns the arguments name/key as string?

function foo(arg) {...}

let user = new User();
foo(user.userId) // => returns string: "userId"
foo(user.name) // => returns string: "name"

For my purposes it would be also okay if the function could return the whole expression, means:

foo(user.userId) // => returns string: "user.userId"
foo(user.name) // => returns string: "user.name"
btx
  • 1,972
  • 3
  • 24
  • 36
  • It sounds like you're after a TypeScript equivalent of C#'s `nameof(expr)`. – Dai Oct 22 '18 at 22:10
  • 1
    Possible duplicate of [Determine original name of variable after its passed to a function](https://stackoverflow.com/questions/3404057/determine-original-name-of-variable-after-its-passed-to-a-function) – Jack Bashford Oct 22 '18 at 22:14
  • 1
    @JBDouble05 Not really a duplicate, that asks about a random variable, this question is about properties, there are sane ways to do this, either in vanialla JS (with proxy) or in a type safe way with `keyof` in Typescript – Titian Cernicova-Dragomir Oct 22 '18 at 22:17
  • @TitianCernicova-Dragomir it just seems very similar – Jack Bashford Oct 22 '18 at 22:18
  • Seen this? https://schneidenbach.gitbooks.io/typescript-cookbook/nameof-operator.html – Dai Oct 22 '18 at 22:20

2 Answers2

1

One option is not exactly a function, but a wrapper, if that's acceptable - you could use a Proxy which intercepts property access and returns the key that was attempted to be accessed:

function User() {}

const userProxy = new Proxy(
  new User(),
  { get: (obj, prop) => prop }
);

console.log(userProxy.userId) // => returns string: "userId"
console.log(userProxy.name) // => returns string: "name"
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

There is no nameof operator in typescript (like in C#). There is the keyof type operator which allows you to specify that a string must be a key of a type. So we could rewrite your function to:

class User {
    userId: number;
    name: string
}

function foo<T, K extends keyof T>(arg: T, key: K) {
    return key
} 

let user = new User();
foo(user, "userId") // => returns string: "userId"
foo(user, "name") // => returns string: "name"
foo(user, "namee") // error

Note There is a nameof implementation for Typescript by fellow SO user David Sherret you can find it here. I have not personally tried it but it may be useful.

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357