I'm aware that modern text editors, IDEs, linters, and even TypeScript itself already alleviate this issue considerably, but they don't quite make it. I'm talking about typeof x == STRING_LITERAL
, which is such a common idiom that VScode has autocompletion enabled for the LITERAL
part.
I propose that JS should have an object or enum (this one is only valid if any of the enum proposals gets to Stage 4) that enumerates all possible values that typeof
could return. A userland implementation would be:
/**
* Strings returned by `typeof`.
*
* For the sake of conciseness, the property keys are shortened.
* I would expect the keys to be equal to the values (only diff being capitalization).
* @readonly
* @enum {string}
*/
const TYPE = Object.freeze({
OBJ: "object",
UNDEF: "undefined",
BOOL: "boolean",
NUM: "number",
BIGINT: "bigint",
STR: "string",
SYM: "symbol",
FN: "function"
})
typeof isNaN == TYPE.FN //true
The problem is the prototype chain, so accessing arbitrary props can return proto-props. Using Object.create(null)
and then assigning prevents static checking, so we can't use it. Using Map
is not a good alternative, because Map
s cannot be accessed using dot notation.
If this was provided as a library built-in, it would be future-proof, because if new types are added it would be auto-reflected on the enum.
TYPE
doesn't need to be a global var, it could be set in an existing (or future) namespace, like Enum
, or something else.
Another solution is to avoid strings altogether and use "raw enums", but that would require a new operator akin to instanceof
, that compares enum values directly like this:
0 typein Enum[Symbol.NUMBER] //true
I took inspiration from Symbol.iterator