5 ms·
Of course they work, I use this in JavaScript all the time. But why would I do that when I have real enum in TypeScript?
by n144q 2y ago
Of course they work, I use this in JavaScript all the time. But why would I do that when I have real enum in TypeScript?
- baobun 2y agoBecause they are nominally typed, which causes issues for users. For example, if you already depend on package foo (depending on package baz@^1.0.1, resolving to 1.0.1) and then add a dependency on package bar (depending on package baz@^1.0.2, resolving to 1.0.3), then the same enums from package baz from the two transitive imports are not compatible, since they are not the exact same instance. So TS won't accept a baz enum returned from foo being passed to a function in bar expecting a baz enum. In this example you could fix it by letting the package manager "dedupe" your lockfile since foo could actually happily also use baz@1.0.3. But if the ranges are incompatible, your best hope is aligning resolutions/overrides. Or fall back to forking and patching packages. And if you're writing your own library interfacing with baz enums, you have to include the full exact version of the originating package to get the right reference. So if baz also has 200MB of total dependencies, you can't opt out of those if you want to reference that 10-line enum in a function signature. As opposed to interfaces and const-types, which you can just vendor (copy-paste exactly what you want) and TS figures it out. You could break the type out to a subpackage. Not so with enums. If you want to extend a union type, you can just add your own with the new element and it will still typecheck. You can not with enums. So you resort to encapsulation or ad-hoc conversion-functions, which gets frustrating and messy very quickly. This is only a concern with enums (and classes, where there is good reason for it as the implementation does matter at runtime in a way that enum primitive values do not). The alternatives don't have this issue - as they are structurally typed, TS will "merge" them at type erasure. If you are 100% sure that your enums stay private inside your module and are never exposed via references in public APIs, at least you're mitigating much of this. But why paint yourself into that corner? (at the point that readability of comments is a concern I suspect you need to reconsider)
- mock-possum 2y agoI know it’s a bit of an extra bullshit, but in the situation you’re describing, can’t you just run the value through a type guard to make the two enums essentially interoperable?
- WorldMaker 2y ago> real enum in TypeScript? I think the point is that enums aren't real in Typescript because enums aren't real in JS. They are fakes that generate a bunch of JS code that you are better off writing by hand (such as examples above and elsewhere, or with libraries like io-ts or Zod or other great options). They are fakes that exist mostly because of a desire for backwards compatibility with the type system of Typescript < 1.0, which also means they are increasingly out of touch with modern types.
- motorest 2y ago> I think the point is that enums aren't real in Typescript because enums aren't real in JS. You used a lot of words to say syntactic sugar. People love syntactic sugar. It solves their problems and makes their life easier.
- WorldMaker 2y agoNo, I used very few words to try to make it clear that enums in Typescript are syntactic salt. Might look sweet from a distance, but it's doing the wrong thing in multiple ways and if you expect it to taste sweet you are in for a surprise. The code generation is ancient and wrong for modern JS. The types are ancient and wrong for modern TS. People do love syntactic sugar. That's why it is important to point out why sometimes it is table salt and they should avoid trying to put it on their desserts.
- motorest 2y ago> No, I used very few words to try to make it clear that enums in Typescript are syntactic salt. They aren't. As others already pointed out, enums greatly simplify some usecases, although they brush the complexity of implementing them under the rug.
- baobun 2y agocan you name some use-case it actually would greaty simplify as you say? Because neither TFA nor this thread has yet proposed anything that isnt better served by later introduced (say TS 3~4.x+) language features or even external libraries if you actually do want to use them for their generated runtime library (enums) and not just their type-aspects. I have only seen them complicate things. You could use it to make typescript prevent forking and code-duplication within a codebase of engineers you dont trust, I guess. But it doesn't seem like a great use either. Consider https://news.ycombinator.com/item?id=42772924 https://news.ycombinator.com/item?id=42772924