Not to mention, there's a slight mental overhead to parsing this. When I see this code, I might wonder if there's a reason for this to be an array. I might wonder if the order is intentional.
An enum has a more clear intent. My only complaint is that enums are not string-by-default, so we end up writing our variants twice:
enum MyType {
A = 'a',
B = 'b',
}To be clear, the enum is also defined at runtime. So this specifically isn't a difference.
Some people will argue a preference for string literal union types over enums because the string literal types don't have any runtime overhead. They just provide type safety at write-time and are bare strings at runtime. But as soon as you start adding arrays and custom type predicate functions to work with them, you're adding runtime objects, which removes that particular advantage over enums.
Substantially. Look at the generated code for an enum.
Also, this approach does not suffer the problems described by the article.
I'll give you that. It looks like the TS compiler (according to the playground site) spits out some code that's intended for maximum compatibility with older versions of JS, even when targeting newer versions (which makes sense, since nothing is technically wrong about it).
It spits out:
"use strict";
var MyType;
(function (MyType) {
MyType["A"] = "a";
MyType["B"] = "b";
})(MyType || (MyType = {}));
when, we would obviously write the following in modern JS: "use strict";
const MyType = {
A: "a",
B: "b",
};
So that's a bit disappointing.So, this could matter if you intend to actually read the emitted JS. If, however, you're TypeScript-only, this is more-or-less the same as reading the ASM spit out by your C compiler or the Java bytecode spit out by javac.
> Also, this approach does not suffer the problems described by the article.
This argument doesn't hold water, unless you're taking a philosophical stance. The argument is that most TypeScript features don't actually spit out JavaScript code and this one does.
But, if you're going to write an array that lists your variants (and then write code elsewhere to check if a string is contained by said array, etc), then "extra" JavaScript code is still being generated- it's just generated by you instead of the TypeScript compiler. Why should we care who generates the code?
This argument only works when we're comparing to writing a string literal union type and no other supporting code for that type. My comment was specifically addressing the case of writing an array to hold our literals instead of writing an enum, and I stand by my claim that an enum is better because it's the same runtime overhead, but more clearly communicates intent/semantics to your fellow TypeScript devs (including future-you).
The IIFE is creating an object only if it doesn't already exist, and adds "A" and "B" to it. "var" doesn't error on a redeclaration, so if MyType already existed you'll get a mashup of the two versions of it. Even if the const was switched to var in the second one, that would still be a straight replacement of the values instead of merging them.
I haven't used Typescript, but I imagine this style was used so enums could gain new values later in the code without having to worry about execution order.
I think I was still accidentally correct in saying that's what we'd write because who the hell actually WANTS the default behavior? :p
Respectfully, philosophy has nothing to do with this.
The argument that the other person made does, in fact, hold significant water. There are extremely long discussions about it on the Typescript GH repo.
.
> The argument is that most TypeScript features don't actually spit out JavaScript code and this one does.
No, it isn't.
.
> then "extra" JavaScript code is still being generated
I never said extra code was a problem. I have no problem with this.
What I said was that I found the code emitted by the enumeration stack to be problematic. You seem to have inferred cause (incorrectly.)
.
> Why should we care who generates the code?
Do you believe that I think a compiler should not generate code?
I never said anything of that form.
Genuinely, it's difficult to hold a discussion with people who read so deeply between the lines that they come to bizarre conclusions, then think those conclusions belong to the person on the other end of the wire.
.
> This argument only works when we're comparing to writing a string literal union type and no other supporting code for that type.
You're not talking about the same argument that I am.
.
> but more clearly communicates intent/semantics to your fellow TypeScript devs (including future-you).
I write documentation.
The article listed literally one reason to not use enums, and that reason is because it requires to compiler to produce JavaScript code. So, if that's not what you're talking about, then I have no idea what "problems described by the article" you could possibly be talking about.
With all of your complaining about my response, you still didn't explain it.