Do you have the same reluctance with classes ? Given that they have the same characteristics than enum, to be both value and type ?
@andrew-burgess2 жыл бұрын
hmm, good question! I don't typically use classes much, but if that's the pattern you're using, I think classes are fine. The nice thing about classes is that they are a type and a value in BOTH TypeScript and JavaScript, so the behaviour is pretty consistent: that is, you can do `myObj instanceof MyClass` in both TS & JS. One thing to keep in mind is that JavaScript doesn't (yet) have private properties within classes, so any private properties in your TypeScript classes will be normally-accessible properties once transpiled to JavaScript. edit: put together some quick examples here: shaky.sh/ts-private-properties/
@po99682 жыл бұрын
Thanks to share your thoughts, Andrew ! Actually, I have difficulty to find a good use case for real classes. I use Java for a long time and JS for 5 years. It seems unnatural in TS, in part, because TS only need the shape of the object to consider the type. Whatever, you have a point to mention the instanceOf operator available in both TS and JS worlds, pretty consistent indeed. Nice article to private properties trick.
@igorswies59132 жыл бұрын
In JS and TS you can use closures instead of classes and that way you don't need to use the "this" keyword
@arnthorsnaer Жыл бұрын
I’ve used enums to great effect in my project. In regards to accept user input and start using it directly in relation to a string enum, I think that in itself is a vad practice and you should always sanitize and qualify the input anyway to see if it matches the enum. So I actually like TS insistance on making devs explicitly use the enum instead of passing in the string.
@MortyCJАй бұрын
2 years old and TS still hasn’t fixed these “issues”. Love the video!
@zavarka22 жыл бұрын
Such a clear and thorough explanation of the enums and the alternative! I finally get it. Thank you, Andrew!
@juniomilnovecientos7 ай бұрын
your alternative became even better with typescript declaration merging which allows us to use the same name for the value and type
@wojciechtomczyk40202 жыл бұрын
Great video! After watching I started thinking, and this is the result: export type Enum = T[keyof T]; const ABC = { A: 'a', B: 'b', C: 'c' } as const; let X: Enum = ABC.B;
@dimitargetsov9690 Жыл бұрын
With my full respect : I removed "extends Object" from and it still works. Any idea why?
@ozzyfromspace Жыл бұрын
First video and I NEED to subscribe. Awesome discussion, Andrew! I look forward to learning from you and suggesting your channel to other devs.
@Metruzanca2 жыл бұрын
The last example is what I ended up doing myself many times. Super frustrating to work with enums. Sometimes they work fine, other times you just end up regretting using them.
@carljmont2 ай бұрын
Also worth noting that in your example, you could have just named your type "PostState" and the const "PostState" instead of "PostStateType" which is more awkward. Because of declaration merging, this is allowed.
@rikuswiehahn8923 Жыл бұрын
This "as const" technique is 🔥 don't know how I didn't come across it earlier, thanks for sharing!
@joostschuur Жыл бұрын
Still new to TypeScript, but at this point, why not just set the type for PostState as a union of strings ("DRAFT" | "SCHEDULED" | "PUBLISHED")? There's a lot of mental overhead for me to process what you used in the end. You still get auto completion. Anything else this doesn't get you? Or is it purely the look of raw strings vs. the more contextual syntax that repeats the PostState part in PostState.Draft e.g.?
@kbitgood Жыл бұрын
You're absolutely right. You don't get anything more than the PostState.Draft object notation vs the "DRAFT" string literal. To me this is purely a code aesthetic choice. When self documenting code is important, especially with multiple developers writing library code with the same enum, then Andrews pattern is nice. But its often overkill.
@ejazmuneeb2 жыл бұрын
I don't subscribe a lot but i am subscribed to you hats off to Andrew great tutorial
@moodynoob2 жыл бұрын
Are there any good use cases for enums beyond when you essentially want named numbers? I used to use them liberally but then found just using unions of strings way more ergonomic.
@andrew-burgess2 жыл бұрын
I haven't come across any cases where a unions of strings doesn't make sense.
@igorswies59132 жыл бұрын
@@andrew-burgess renaming
@andrew-burgess2 жыл бұрын
@@igorswies5913 hmm, can you say more? not sure I follow.
@igorswies59132 жыл бұрын
@@andrew-burgess I don't think you can rename a string from a union using F2 and have it be updated everywhere, can you?
@andrew-burgess2 жыл бұрын
@@igorswies5913 Oooh, gotcha! Yeah, that's a good example! The best you get in that case is that after you update the union, the type checker will tell you all the places that no longer match the union. But you'll have to update them manually :(
@33v4.2 жыл бұрын
I look forward to seeing your channel growing my fren! awesome content
@LukaLightBringer2 жыл бұрын
In which scenario would using the same name for the type as the variable be a problem? Surely the type names don't have any relevance on the variable names in typescript, isn't the language always lexicographically disambiguous in whether you're refering to a type or a variable?
@vaap Жыл бұрын
as far as im aware, yes. i do that all the time lol. very useful as an export
@e2e23e2 жыл бұрын
Very clear explanation. Thanks for sharing.
@ejazmuneeb2 жыл бұрын
🤯🤯Shocked to see such low subs? absolute great content.
@catwhisperer911 Жыл бұрын
They are the Devil incarnate! LOL I never use them. Thanks for sharing.
@BrianBall-h9x Жыл бұрын
I use a very similar solution, but instead of "as const", I wrap my object literal with Object.freeze, which has the same TypeScript benefit of "as const" and also protects your object at runtime from someone making changes to it.
@julianli51202 ай бұрын
Object.freeze won’t protect object modification when it has nested attributes
@jasonrooney1368 Жыл бұрын
I ran into an interesting problem with this pattern. If you want to use an enum-like for a generic argument, an actual enum will work, but the as const version will not. If you try to pass Post, it will complain that PostStateType is not a known namespace. However, you can still use the literal value Post. On the other hand, with enums, you can use it directly as a generic argument i.e. Post
@fahadahaf Жыл бұрын
You can pass `Post` instead and it would work, You can even make it nicer by making a type alias for `type X = typeof PostState` and now you can do it like this `Post` if you prefer. the only downside that you can't use the dot operator; so you have to do `X['Draft']` instead of `X.Draft`.
@fahadahaf Жыл бұрын
``` type PostStateK = typeof PostState type PostStateV = PostStateK[keyof PostStateK] interface BetterPost { id: number state: State } const y: BetterPost = { id: 2, state: 'DRAFT' } ```
@tmbarral664 Жыл бұрын
@11:47 ok, it works......but.... I want to forbid the use of string here, I wish to force the use of PostState.Draft as a sngle source of truth. As a matter of fact, I was using enum and not union for that very reason. Any suggestions ?
@kardashevr Жыл бұрын
use const enums
@developerfriendly2 жыл бұрын
great tutorial, thanks!
@roynilsson1382 Жыл бұрын
Awesome video. helped me allot.
@markokraljevic1590 Жыл бұрын
why is there no link from the code?
@chunkwanchan5503 Жыл бұрын
the best!
@dixztube2 жыл бұрын
Go kinda avoids enums I use them in strapi but generally kinda keep away from em
@andrew-burgess2 жыл бұрын
It's been a while since I dabbled in Go! But Rust enums are absolutely THE BEST. I think the union type + exhaustive switch pattern in TypeScript took a lot of inspiration from Rust enums.
@officemax39772 жыл бұрын
nice blooper at the end there :D
@andrew-burgess2 жыл бұрын
😂
@2tvtv2 жыл бұрын
🙏🙏
@tvujtatata Жыл бұрын
Its funny how TypeScript refuses to add some QoL because it would affect the resulting JS code and then enums exist lol.
@ransomecode Жыл бұрын
Yes you shouldn't use them; JavaScript Symbols exist for that reason (according to MDN) for instance: ``` const Colors = { RED: Symbol("❤️"), BLUE: Symbol("💙"), GREEN: Symbol("💚") } ```
@kbitgood Жыл бұрын
I think you can absolutely have both the constant and the type have the same name "PostState". Since one is a value and one is a type they won't collide. Typescript knows when you are using it as a value and when you're using it as a type. And it also gives the exact same DevX as Enums because an enum is both a type and a value.
@Chris-jm2gx Жыл бұрын
why even bother with enums or object as consts if you can just use union types of specific values?
@rutabega3067 ай бұрын
Refactoring is a bit easier if you can search for the enum/object name
@evccyr7 ай бұрын
Honestly typescript doesn't really give any feel of a strongly typed language. It also adds to the complexity.
@andrew-burgess7 ай бұрын
Ooh, that's a take I haven't heard before: that TS isn't strongly-typed. Say more?
@ginger-viking2 жыл бұрын
Good video, annoying music. Subscribed.
@andrew-burgess2 жыл бұрын
Thanks! Yeah, I’ve gotten feedback on the music, and have been (I hope) improving that.
@Threnode Жыл бұрын
5:00-5:45 Why the hell would you use numbers anyway if you can use human-readable form? Why purposely add obscurity to your own code... 7:00-8:27 Using strings is prone to typos and when you need to change the value, you have to do it in only one place. If you need to change the reference, you always know where it comes from. When you have an object that holds your constant values, why would you type in a value itself, when you can refer to that object? If you want to do otherwise, why to create enum at all? And what is wrong with importing from library? Isn't it a good thing if a library provides you with a more flexible (I mean, that can be used as a type and value) contract of using it? Imo, what you said about enums should be presented not as flaws, but as peculiarities. One should be aware of them, true.
@mahadevovnl Жыл бұрын
I think enums are a mistake in TypeScript. It should be removed. Just like "interface" should be removed and its (very few) unique features should be included in "type". Unfortunately, the TypeScript group is too careful too often. Just remove it in the next major release. Most people won't care because most people aren't using it.
@rex_melynas2 жыл бұрын
Can't we just get a lesson from C++ and have enum classes ? enum class State { Draft, Scheduled, Published, } // Nope const x: State = 0; // TS: Error, invalid value for State, should be `State.Draft`, `State.Scheduled` or `State.Published` // Still Nope const x: State = 3; // TS: Error, invalid value for State, should be `State.Draft`, `State.Scheduled` or `State.Published` // Nope Again const x: State = "Draft"; // TS: Error, invalid value for State, should be `State.Draft`, `State.Scheduled` or `State.Published` // Yep const a: State = State.Draft; const b: State = 1 as State; // Explicit cast const c: State = 5 as State; // Will work, but you shouldn't use this.
@andrew-burgess2 жыл бұрын
Yeah, other languages do it so much better. I’d love rust-style Enums in TS, where you can store values and do matching (you can kinda get this pattern with an exhaustive switch and union type in TS)