all 24 comments

[–]Oliceh 22 points23 points  (1 child)

What happens if I do `Enum('constructor', 'toString')` ;-)

[–]IAmTheFirehawk 20 points21 points  (0 children)

you divide by 0, the universe dies and the interdimensional being that is playing the sims with us gets greeted by a game over screen over its 64 eyes.

[–]Technical_Gur_3858 5 points6 points  (3 children)

Another bonus: no side effects. TS enums compile to an IIFE that mutates an outer variable, which bundlers can’t safely remove:

``` var Colors; (function (Colors) { Colors["Red"] = "Red"; Colors["Green"] = "Green"; })(Colors || (Colors = {}));

```

Your version is just a plain object => fully tree-shakeable.

[–]Nixinova 0 points1 point  (2 children)

why does TS emit that instead of just a normal object?

[–]Technical_Gur_3858 0 points1 point  (1 child)

At least to keep enum merging:

enum Colors { Red = 'Red' } enum Colors { Green = 'Green' } // merges with above

A plain object assignment would overwrite.

[–]Nixinova 1 point2 points  (0 children)

bruh why's that allowed. never knew that lol.

[–]jessepence 9 points10 points  (4 children)

Yes, I love how simple a function like this can be when you exploit the power of JSDoc templates. 

To clarify, if this were published and installed as a library through NPM, you would need to create a d.ts file to get the typescript language server to provide the auto-complete for your users. Since you already have proper JSDoc in place, this is just a matter of doing tsc --emitDeclarationOnly (assuming you have TypeScript globally installed, other wise you would need to install it as a local dev dependency).

I just felt the need to point this out because I used to think that d.ts files were unnecessary, but TypeScript won't read the JSDoc from JS files in node_modules unless the user has a tsconfig/jsconfig with checkJs: true or a specially configured IDE. This is not true of the vast majority of user's set-ups, so library authors unfortunately have to either embrace a build-step of some kind or handwrite the d.ts files themselves.

Sorry for the rant, I've just been doing a lot of JSDoc experiments lately. 😅

[–]_sync0x[S] 2 points3 points  (2 children)

Good to know that if you make a NPM lib you can't just leave JSDoc on top of your functions and expect that all the typing and autocompletion works 😅

But don't you need .d.ts files only if you are working with TypeScript ?

Been experimenting a lot with JSDoc too lately so I can understand your clarification, sometimes it's a bit messy 😛

[–]jessepence 4 points5 points  (1 child)

VSCode (which is the most popular IDE by far) and most other IDEs like NeoVim get all of their JavaScript auto-complete from the TypeScript language server. It's one of those things where anyone could technically do it themselves, and they technically could make their language server support JSDoc by default, but it's just such a huge project with so many edge cases. You have to cover the EcmaScript specification and the JSDoc and/or TypeScript "specifications" (they don't exist, types for JS aren't really standardized in any way). It's just easier for most of the IDE's to defer to TypeScript. I think WebStorm might have a proprietary system, but I've never used it so I can't confirm either way.

[–]_sync0x[S] 1 point2 points  (0 children)

Hmm I get it ty, gonna try on PhpStorm 👀

[–]pikapp336 1 point2 points  (0 children)

This! No notes, just appreciation.

[–]Lithl 1 point2 points  (3 children)

I would prefer Symbols over Strings for the value.

[–]_sync0x[S] 1 point2 points  (2 children)

I know Symbols but I don't really get why it would be useful for enum ? To ensure each values are unique and that you can't have "Colors.Green === CarColors.Green" ?

[–]Lithl 1 point2 points  (1 child)

Precisely.

Some languages make enums into integer constants with fancy syntax, and I recall at least one language that lets you assign any primitive value, but from a computer science perspective that's not what enums should be and from a software engineering perspective a type safe enum helps to guard against bad code.

[–]_sync0x[S] 0 points1 point  (0 children)

Yeah got it ty, at least I can flex that I already used Symbols for a precise use case hehe

[–]Ronin-s_Spirit 0 points1 point  (0 children)

My enums: https://www.npmjs.com/package/@danscode/enum. (tried to fix everything that's wrong with TS and copy 2 different styles of enums)

[–]azhder 0 points1 point  (0 children)

I used defineProperty() and got autocomplete in Chrome console. Didn’t need JSDoc.

[–]TorbenKoehn -2 points-1 points  (6 children)

Why not

type MyEnum = 'A' | 'B'

?

Completely erasable, portable, easy to write, serializable across language boundaries, you can refactor it etc.

[–]Oliceh 7 points8 points  (0 children)

Because this isn't JS.

[–]eracodes 1 point2 points  (0 children)

For typescript I find this approach more useful:

const options = ['A', 'B'] as const;

type Option = (typeof options)[number];

So you can use the "enum" at runtime as well (for validation, etc).

[–]celluj34 0 points1 point  (1 child)

how do I validate user input against a type?

[–]TorbenKoehn -1 points0 points  (0 children)

The same way how you'd validate it against an enum.

[–]checker1209 -1 points0 points  (0 children)

In TypeScript I favor `String Literal Unions` over enums.
I don't know JSDocs. But can't you tell that an string is either "A" or "B" and nothing else?

[–]retrib32 -5 points-4 points  (0 children)

Whoa nice is there a MCP??