No video

Let's Talk About TypeScript's Worst Feature

  Рет қаралды 50,566

Theo - t3․gg

Theo - t3․gg

Күн бұрын

Please tell me you're not still using enums. Let's leave them behind in 2022.
#t3stack #fullstack #webdevelopment
ALL MY VIDEOS ARE POSTED EARLY ON PATREON / t3dotgg
Everything else (Twitch, Twitter, Discord & my blog): t3.gg/links
S/O Mir for the awesome edit 🙏

Пікірлер: 341
@t3dotgg
@t3dotgg Жыл бұрын
Some of y'all are REALLY misreading the example at 0:50. Read this slightly changed version before commenting about it. const user = {id: 1, role: UserRole.User) if (!user.role) { user.role = UserRole.Unassigned }
@tomashaddad
@tomashaddad Жыл бұрын
Say you were able to tolerate assigning the first variant of UserRole to =1 to avoid this issue. Would this change your opinion?
@ChillAutos
@ChillAutos Жыл бұрын
I don't think this is the case. People here raised legitimate questions because you completely ignored the fact you can just do enum User { Admin = "Admin", Staff = "Staff", } To address enums without even mentioning that in this context is kinda funny. Then you just screamed thats just string literals with extra steps, which again is stupid. Typescript is just javascript with extra steps, does that make it worse? Ofc my example is disingenuous as well but thats the point, I didnt explain any of the other benefits of typescript, if I made a video like that i'd be right to have people calling me out for my shitty example.
@juniorfr4890
@juniorfr4890 Жыл бұрын
@@tomashaddad ' _"Number is terrible js feature, 0 may get interpreted to *false*. Here i show you how i avoid that with an array of string containing every number... you can even iterate it"_ (feel free to delete my comment theo.)
@dagonzalez1757
@dagonzalez1757 Жыл бұрын
do you always treat your viewers as morons? get off your horse
@powerinemesitsunday236
@powerinemesitsunday236 Жыл бұрын
@@ChillAutos Thank you. I was about to comment the same. I use enums a lot (exactly how you described), and I don't see how his boilerplate-y code is better than enums. Utter crap.🙄 I could iterate through an enum, use it as a (string constant) type and use its values as well (like an object just as his boilerplate-y code showed) and the DX is way better. Theo, you should not talk about a feature if you're not really sure how it works. Do your research well before coming out at us. 🙄
@alisharobinson7146
@alisharobinson7146 Жыл бұрын
Use it like so enum ThemeOption { lightTheme = 'light-theme', darkTheme = 'dark-theme', } The reason for enums is for more readable global reused variable values when referencing them in HTML or TS. You just have to make each value equal to a string value that makes sense otherwise you will get the weird number index value. People are more likely to understand the enum than making custom types based on an array which is more advanced. I teach typescript and can confirm this is less overhead than your way and more readable.
@aaronv7685
@aaronv7685 Жыл бұрын
right I think this is easily solved by string enums?
@AlcoCZ
@AlcoCZ Жыл бұрын
This.
@HOLYCC
@HOLYCC Жыл бұрын
This is the way. I don't know how the hating of enum started becoming a trend, but for a set of options, why does Theo's path require multiple blocks, instead of just doing an enum this way. Cleaner, more readable, and most importantly it accomplishes the same thing.
@fyfirman
@fyfirman Жыл бұрын
Very agree with your answer 👍🏻👍🏻👍🏻
@JonathanGalentine
@JonathanGalentine Жыл бұрын
This is how we use it at my day job too.
@sihoonkim1502
@sihoonkim1502 Жыл бұрын
Or you can just do this..! U dont have the "zero" issue with the first enum element, u get typesafety, And u can easily iterate on it with Object.values(UserRoles).map( role => .... ) enum UserRoles { User = 'User', Admin = 'Admin', Staff = 'Staff' }
@OleksandrDanylchenko2k
@OleksandrDanylchenko2k Жыл бұрын
Agree 👍 I believe it's much simpler and ideomatic than having an array
@t3dotgg
@t3dotgg Жыл бұрын
This is just string literal types with extra steps
@ChillAutos
@ChillAutos Жыл бұрын
@@t3dotgg is it though? This seems to be on par with your second array example. With the added benefit that everyone knows what an enum is and it's pretty clear exactly what is happening here. I really don't think this is extra steps at all, and if there is still an issue with the example posted here then I'd be interested to hear it. I myself are started using string literals a lot recently like your first example after watching someone else's video which was very similar but it still doesn't seem super clear that enums suck completely, just that enums like in your first example do suck.
@ilearncode7365
@ilearncode7365 Жыл бұрын
This is the way
@ilearncode7365
@ilearncode7365 Жыл бұрын
Its even more useful when the key and value arent the same, so you can do colors.brown and not memorize hex values etx
@MarcelRobitaille
@MarcelRobitaille Жыл бұрын
Why would you ever write the condition at 0:50. It doesn't make any sense.
@MarcelRobitaille
@MarcelRobitaille Жыл бұрын
@Duy Phạm Bá Xuân Yes, I saw that in another thread. Still no reason to do if (Enum.VARIANT) I see why you would do if (user.role). I'd do !== null or something though (and use TS to ensure it could only be those two types)
@DuyPham-kk8hw
@DuyPham-kk8hw Жыл бұрын
@@MarcelRobitaille Oh! I usually have to check it at work because different enum has different logic For example: If(ERoles.Admin){} else if(ERoles.Employee){} So the video makes sense to me
@DuyPham-kk8hw
@DuyPham-kk8hw Жыл бұрын
@@MarcelRobitailleDoes it make sense to you ?
@DuyPham-kk8hw
@DuyPham-kk8hw Жыл бұрын
@@MarcelRobitaille oh, i get your idea now.. yea :D Hmm, theres no reason to do if(Enum.VARIANT).
@MarcelRobitaille
@MarcelRobitaille Жыл бұрын
@@DuyPham-kk8hw That code would be for the instance of the enum, not the enum type itself
@gamertike
@gamertike Жыл бұрын
In defence of enumes, when have you ever used if (UserRole.User) { ... } instead of if (user.role === UserRole.User) { ... }?
@Andreas_Mann
@Andreas_Mann Ай бұрын
first time i watched one of his vids and that alone told me he's a clown
@loomy5113
@loomy5113 Жыл бұрын
Perhaps I'm not understanding the issue fully, but aren't these problems already solvable by either declaring the first value of the enum as 1 (e.g. enum UserRoles { User = 1, Admin, ... }), or by declaring your enum values as string literals (e.g. enum UserRoles { User = "user", ... })?
@sdot0
@sdot0 Жыл бұрын
That’s what I came to type. That would have been a much easier solution. Golang uses constant/iota instead of Enums and you can change the default value (also 0) with them as well.
@thienhuynh7962
@thienhuynh7962 Жыл бұрын
kzbin.info/www/bejne/oJuwk4OqlK1miLM I came across this explanation and it's much clearer to why enums are bad compare to theo's, do check it out
@qorzzz9252
@qorzzz9252 Жыл бұрын
String enums are fine IMO. What you demonstrated as the "problem" is this video is easily mitigated by adding string initializers to the enum values. Your solution does give access to an array of string values you can iterate (such as dropdown in your case) however, your solution also has a pretty massive flaw in that you must do checks against string literals. For example, with your solution you cannot say: if(user.role === UserRoles.Admin) instead you must write if(user.role === "Admin") and this is incredibly cumbersome if you have either: A) Many points where you check these values or B) many values that you do checks against.
@iMagicGraalOnline
@iMagicGraalOnline Жыл бұрын
For the "if (UserRole.User)" returning a falsy, why would you EVER want to check for that? Even if you wanted to check if it exists, its an enum which will never be changed by the code you write so as a developer you'd just know it does exist. Thats like checking for an "if (false)" statement and being surprised that it's not hit.
@yapdog
@yapdog Жыл бұрын
That's exactly what I'm saying. I have no idea what the problem is that he's illustrating.
@jpbastyr
@jpbastyr Жыл бұрын
the case i would assume it comes up in is when the role is part of another object like User, then checking if they have a role set like `if (user.role && user.role === UserRole.User)`, if the user.role is 0 it will be falsey and the condition will be false even if they actually are a UserRole.User of course in this case its probably not necessary to check the role before equality comparison, but regardless the situation is probably not specifically checking the enum declared itself but rather when its part of another type
@ChillAutos
@ChillAutos Жыл бұрын
Think about getting data back from some api with that user role and you're checking to see if that data was returned correctly.
@SaHaRaSquad
@SaHaRaSquad Жыл бұрын
@@ChillAutos You'd have exactly the same issue if the field was an integer, and 0 would even be a valid value in that case. I just don't check anything in JS/TS without ===, it's consistent across all situations and the "cleaner" code ain't worth it.
@user-lb8to5yr6r
@user-lb8to5yr6r Жыл бұрын
Yeah, I've never seen that someone does something like if (UserRole.User) with enum. It's nonsense.
@desengenho1539
@desengenho1539 Жыл бұрын
Here in Brazil, we would call you a Caga Regra but with affection and love This video only reminds me of that guy who told Mike Tyson to grab him by his wrists and made an awesome karate move to get out, and Mike just asked, " Why would I grab you by your wrists if I can punch you in the face? Why would I check the truthfulness of an enum value?
@ronbiton8799
@ronbiton8799 Жыл бұрын
It is a cool solution but you will be forced to deal with random strings located in random pieces of your application. You will not be able to use the list of enum values as you would with an enum. So a basic condition turns from this: if(user.role === UserRoles.Admin) // Which is not only type safe, but also allows for an easy change of either key or value to this: if(user.role === "Admin") // Which might still be type safe, in the sense that you won't be able to compare it to values that are not part of the type, but you loose some of the consistency an enum is giving you. I do have a fare share of problems with enum, but this will not be a good enough replacement for me.
@pxkqd
@pxkqd Жыл бұрын
Thanks for covering this up for everyone! I prefer the variant with object instead of array: const UserRoles = { User: 'user', Admin: 'admin', Staff: 'staff', } as const type UserRole = ObjectValues Using this auxiliary type ObjectValues = T[keyof T] This way you still get UserRoles.Admin which is one of the features of enums people like.
@paulrukavishnikov5171
@paulrukavishnikov5171 Жыл бұрын
Why not this then? enum UserRoles { User = 'user' Admin = 'admin' }
@mahmutjomaa6345
@mahmutjomaa6345 Жыл бұрын
They can have the exact same name + you can freeze the object. const UserRole = Object.freeze({ User: 'user', Admin: 'admin', Staff: 'staff', } as const); type UserRole = ObjectValues;
@trontor.6711
@trontor.6711 Жыл бұрын
@@paulrukavishnikov5171 because you can't iterate over the values.
@paulrukavishnikov5171
@paulrukavishnikov5171 Жыл бұрын
@@trontor.6711 Object.values(YourEnum).map works perfectly
@C0DSwAgGeR98
@C0DSwAgGeR98 Жыл бұрын
enum UserRole { User = '0', Admin = '1', Staff = '2' } This works using an enum. the literal can be whatever you want it to be. iterating and key access of native enums. can use zod descrimated unions with them. Avoids the null value of the first element.
@Nil-js4bf
@Nil-js4bf Жыл бұрын
I use string literals and arrays as much as possible. String literals are nice in that you don't need to import it to use it as a value but it's a double edged sword because that also means you can't click the type to find all its usages.
@yapdog
@yapdog Жыл бұрын
Being a C coder, I really have no idea what the problem is that you're illustrating. I mean, *of course* User == 0. What am I missing???
@refinery__
@refinery__ Жыл бұрын
Checking for "if (SomeEnum.User))" will return false because "Boolean(0)" returns false too, so you cant properly check for truthiness here
@yapdog
@yapdog Жыл бұрын
@@refinery__ If the goal is to check if SomeEnum.User has been set to something, that doesn't make any sense at all. Enums aren't objects/structs. They're constant values. Think of it like compiled code with #define USER 0. USER is a placeholder for 0, and you can't change the value of 0. So using an enum as an object is bad. I've seen the various examples posted by the KZbinr, but all of them lead back to that central conclusion: a misunderstanding of the purpose of enums, not that enums shouldn't be used.
@wojciechosinski5927
@wojciechosinski5927 Жыл бұрын
@@yapdog I think it's kind of a lacking example to do if(). Even in TS/JS it doesn't make sense to check "if value". (if value is what???) He should present it as if(value === ), but then you don't really have any issues with enums in general. Though in TS it's kind of a bad practice to set first enum as 0 cause it's falsy. It's easier on mind to just assign truthy valeus in enum, so you won't be bothered by potentials bugs with it, but it's still a matter of opinion tbf. I prefer to set enums with strings as values.
@nomadshiba
@nomadshiba Жыл бұрын
quick note: enums in my opinion are not meant to be used like that enums are suppose to be numbers that you can do bit operations on in this sense you should only use `const enum` and if you are using `enum` you probably not looking for enum and looking for: const Roles = ['admin', 'moderator', 'user'] as const type Role = typeof Roles[number] or const Roles = new Set(['admin', 'moderator', 'user'] as const) type Role = typeof Roles extends Set ? T : never
@Disorrder
@Disorrder Жыл бұрын
Nonono. Please, stop forcing people to stop use enums! Nobody checks if (UserRole.User). It’s nonsense! Check if (user.role === UserRole.User). That’s correct for any language
@algirdaspaskevicius5690
@algirdaspaskevicius5690 Жыл бұрын
enum UserRoles { User = 'user' }. This way, you avoid the problem. Have type safety, have dot syntax, and less code...
@cotneit
@cotneit Жыл бұрын
I'm not sure why you went with an array example, if someone can get away with using array as const they never needed that enum in the first place, object as const is usually what enums are substituted with to avoid "magic values" (I'd say the only thing enums have going for them is that they enforce enum symbol usage instead of literal value, which makes refactoring and reference finding much more reliable) const UserRole = { User: 'user', Admin: 'admin', Staff: 'staff', } as const; type UserRole = typeof UserRole[keyof typeof UserRole] // replace with utility type to reduce ugliness const USER_ROLES = Object.values(UserRole);
@Disorrder
@Disorrder Жыл бұрын
Enums compiled into object. Why don’t to use enums then? They are semantically **enumerate**
@cotneit
@cotneit Жыл бұрын
@@Disorrder Enums compile into objects with unwelcome additions that unnecessarily complicate things
@cotneit
@cotneit Жыл бұрын
@@Disorrder You will actually notice that if you try to run Object.values() on enum with numeric values
@dealloc
@dealloc Жыл бұрын
Enums are transpiled into IIFE's not objects (they are evaluated into objects at runtime) and are not tree-shakable unlike object literals. It will appear in the bundle, whether you use the enum or not.
@axeld.santacruz4659
@axeld.santacruz4659 Жыл бұрын
Me looking for this video, at 9:45 p.m. when doing some react. Good content, mate.
@interneb
@interneb Жыл бұрын
I never liked the whole idea of typescript paradigms trying to shoehorn their way in to a valid JS construct at build time
@EthanStandel
@EthanStandel Жыл бұрын
TypeScript doesn't like it either and the devs have expressed regret on adding anything that has runtime effects like enums & namespaces.
@t3dotgg
@t3dotgg Жыл бұрын
Thankfully the TS team seems to agree and has stopped doing this
@DEVDerr
@DEVDerr Жыл бұрын
Enums with strings basically solves all the problems presented here
@Chris-Clicks
@Chris-Clicks Жыл бұрын
Just set the enum values to strings with the same name? Why would you create an enum without giving the options values (a string in most cases)?
@jpbastyr
@jpbastyr Жыл бұрын
it helps with serialization too to use strings, instead of relying on your server side and client side be declared even in the same order
@lmao6
@lmao6 Жыл бұрын
At my company we had a huge chunk of code migrated out of a single code base to a shared component library. There was heavy use of enums and it’s awful. You try and mix types with your own app's and you always have to pull in enums from the shared library to make typescript happy. String unions solved the issue and makes things a lot nicer to work with. (Hint, its also whats used by all the large open source typescript projects) My recommendation is if you want to use enums, they should be isolated in your own module and not be exposed to others in your interfaces.
@zactron1997
@zactron1997 Жыл бұрын
"What if we replace standard notation with non-standard notation but just all remember it and not rely on our build tools to do it for us?" What you've done here is replace a simple concept applicable in most languages with a hack that only works in some languages, in order to get some of the same behaviour. And you've polluted your namespace with duplicates of every enum in order to be able to enumerate over the possible values, and you've made the size of a user structure substantially larger by requiring the storage of an entire string where a short would've sufficed. This is bad advice and you should post a followup.
@MonsterlessonsAcademy
@MonsterlessonsAcademy Жыл бұрын
Enums are amazing if you use them correctly. Which means with strings as values. Then you can amazing typings and values in your code enum UserRole { admin = 'admin', user = 'user' } if (user.role === UserRole.admin) // it's a valid check when user came from backend for example because we have a value and a type. interface UserInterface { // here is super confortable to use enum as a type. id: string; role: UserRole }
@MichalSmolinsky
@MichalSmolinsky Жыл бұрын
It's a silly video to get our attention😄
@Retro.one4
@Retro.one4 Жыл бұрын
While I agree with you on typescript enums. With this method you lose the dot syntax for uses elsewhere. Say when you want to query Users.Admin you have to use User[1]. Using indexes is worse than not being able to iterate. I've been messing around with using objects and typeof keyof, Object.entities as a replacement for enums and and arrays, but this is a work in progress.
@theory-in-motion
@theory-in-motion Жыл бұрын
Doesn't need to be work in progress. It's the hands-down better way of doing things, 99% of the time, for things that could be enumerations or static config objects.
@xxri552
@xxri552 Жыл бұрын
I like these short typescript videos, make more of them in the future, please!
@powerinemesitsunday236
@powerinemesitsunday236 Жыл бұрын
This particular video about enums is misleading. Don't take his advice.
@Cmacu
@Cmacu Жыл бұрын
Please for the love of coding, don't follow his advice.
@robertotomas
@robertotomas Жыл бұрын
You’re wrong. Typescripts enums aren’t great for sure, they are overly complex, but “bare string” solutions are just worse in every way.
@codewithguillaume
@codewithguillaume Жыл бұрын
I have to admit: this is really good stuff.
@AfterDarknes
@AfterDarknes Жыл бұрын
that's an extremely bad example why enums are bad. If you need a string representation of the enum then i would accept it, but even then the proper solution is to have a procedural macro, just like rust, that generates the "to_string" implementation of an enum automatically.
@wojciechosinski5927
@wojciechosinski5927 Жыл бұрын
typeof UserRoles[number] is so unintuitive. I believe It's more readible to use enums as collection of key value pairs with strings as values instead of implicitly assigned numbers that can be falsy as it's presented
@adamshiri4902
@adamshiri4902 Жыл бұрын
the main problem of Enums is when you change order you will have unexpected behaviors (value changed). I only use it with string values...
@rizanfs
@rizanfs Жыл бұрын
literally what I search yesterday.. it's crazy that you immediately roll out this video
@quelchx
@quelchx Жыл бұрын
I like enums (come from Java land before getting job were no Java is required). I don't use em often, but I like using them say for quick example off the top of my head -- logging things (create enum of possible log types or whatever). I know they're many ways to avoid enums but that's the beauty of programming everyone has a preference to how they describe things.
@BigBahss
@BigBahss Жыл бұрын
Why not just set your enum values to strings instead? That's what I do, solves these issues in a more elegant way imo. Plus, what is be the purpose of the expression: "If (UserRole.User) {}" Why would you ever write that? What is that meant to be accomplishing? If you're not explicitly checking for undefined/null on your literal types, then you're going to run into problems sooner or later when you come across a value of zero or an empty string. Besides, isn't it pretty common convention for numerical enum values to begin at zero unless otherwise initialized?
@ryanngalea
@ryanngalea Жыл бұрын
String enums are god tier, never use otherwise
@MichaelAuerswald
@MichaelAuerswald Жыл бұрын
String enums do not have those issues AND you can loop over their values, something you can't do with type literals (at least not straight forward) . Literal Types are great (e.g. Template literal types) but they do not replace all use cases for string enums. Also the DX is worse (imho) AND they disappear at runtime, while enums are just objects. Both have their uses.
@dealloc
@dealloc Жыл бұрын
Enums are not just objects, they are compiled to IIFEs (immediately invoked function expressions), meaning that they add additional implicit overhead both in runtime, but also in bundle size shipped to users. IIFEs cannot be tree shaken because have to be invoked on initialization. So even unused enums will be end up being bundled, even if you aren't using them anywhere. Oh, but why not just use const enum then? Then they will be stripped away! In application code, sure if your entire codebase is 100% TypeScript, because there's no interopability between JavaScript, which cannot import or access const enums and have to use literal types, and TypeScript, which is required to use the enums due to its constraints. The solution? Unions. If you don't need the values at runtime, specify them as unions. If you need the iterate over the values, you can use a readonly array and get the type for each value as a union. If you really need to access them through dot notation, you can use a readonly object literal and get the types for each of the values. You can even name the type the same as the variable. Additionally, if you don't use the values in runtime anywhere, they won't be bundled, so they are essentially free.
@offroaders123
@offroaders123 Жыл бұрын
Thank you!!! This works really well, I'm so glad you made a video about it.
@jadolow_
@jadolow_ Жыл бұрын
This is not how enums are supposed to be used. They are not lists, you are not supposed to iterate through them or use them in conditional statements the way you showed. The main use of enums is to strongly type parameters, properties, and return values that represent sets of values. Using the UserRole example: enum UserRole { User, Admin, Staf } class User { name: string; role: UserRole; constructor(name: string, role: UserRole) { this.name = name; this.role = role; } } let exampleUser = new User("John", UserRole.User); if (exampleUser.role === UserRole.User){ console.log("I am a regular user!") } Here we have a strongly typed field and we can compare it against it's possible values as opposed to using magic strings. Saying "It's so much easier to work with the values when you ignore the weird behaviors of enums by throwing them out entirely" in this situation is like trying to add "2" + "2", being surprised why the result is "22" and not "4", and then saying "It's so much easier to work with the values when you ignore the weird behaviors of strings by throwing them out entirely". Lets not throw out string or enums. Let's use the tools we have for the things they are designed to do.
@xReDxTuRtLeZx
@xReDxTuRtLeZx Жыл бұрын
love these types of short "hey heres a small piece of typescript you may want to rethink" as its much easier to digest small topics so i dont have to prepare to watch a long discussion with too much info for one sitting.
@doronsages983
@doronsages983 10 ай бұрын
one video id like to see about ts is all the interactions with data that comes from backend, or generally from outside the codebase.
@cotneit
@cotneit Жыл бұрын
0:54 - Ok I don't like enums too but why would you ever do that
@t3dotgg
@t3dotgg Жыл бұрын
const user = {id: 1, role: UserRole.User) if (!user.role) { user.role = UserRole.Unassigned }
@cotneit
@cotneit Жыл бұрын
@@t3dotgg Ah, thanks, now I'm getting flashbacks
@PhilipAlexanderHassialis
@PhilipAlexanderHassialis Жыл бұрын
Have you seen juniors or pretend "mid"'s code? You will be amazed at what you will see. Thoroughly amazed.
@MarcelRobitaille
@MarcelRobitaille Жыл бұрын
​@@t3dotgg If you ask me, that's a problem with TS's implementation, not with enums themselves. Also, I would say your code example is bad code. Put a type on user so role is UserRole or null and check explicitly for null. Lots of things in javascript are falsy, not just enum variants. I would also argue here that TS needs a better Option type.
@cotneit
@cotneit Жыл бұрын
​@@MarcelRobitaille That's exactly what he's saying, it's a problem with TS implementation, not enums in general If you start explicitly checking for null, you would also have to be explicitly checking for undefined Option type in typescript wouldn't make much sense, it's like trying to use only null or only undefined, external dependencies will mess everything up and making abstractions over them is just not worth the overhead
@rvgn
@rvgn Жыл бұрын
Yes! Here's my preferred replacement for Typescript enums: ```typescript const USER_ROLE = { USER: "user", ADMIN: "admin", STAFF: "staff" } as const; type UserRole = typeof USER_ROLE[keyof typeof USER_ROLE]; ``` It's still easy to iterate with `Object.keys()`, `Object.values()` or `Object.entries()`.
@NuncNuncNuncNunc
@NuncNuncNuncNunc 10 ай бұрын
Replace 'const USER_ROLE =' with 'enum UserRole', replace ':' with '= ', and delete 'as const;' and 'type UserRole...'
@rvgn
@rvgn 9 ай бұрын
@@NuncNuncNuncNunc why would I do that? Did you watch the video? The point is to *not* use Typescript enums. My code gives me everything I might want from enums while avoiding any surprising or unwanted behavior.
@yarrichar
@yarrichar Жыл бұрын
The array for iteration was super helpful - thanks!
@powerinemesitsunday236
@powerinemesitsunday236 Жыл бұрын
I like some of what I see in the comments. This video is utter crap. How dare you say enums is the worst TS feature. You certainly don't know how to use it best. 🙄 I use enums a lot (exactly how someone, @Rick, described), and I don't see how your boilerplate-y code is better than enums. Utter crap.🙄 I could iterate through an enum, use it as a (string constant) type and use its values as well (like an object just as your boilerplate-y code showed) and the DX is way better than yours. You should not talk about a feature if you're not really sure how it works. Do your research well before coming out at us. 🙄
@coffee-is-power
@coffee-is-power Жыл бұрын
Rust enums are the exact opposite of the ts ones, they're the enums everyone has dreamed of since forever.
@Saturn2888
@Saturn2888 Жыл бұрын
I made a decision to stop using enums recently for similar reasons. They _seem_ right because they're in other languages like C++, but that doesn't mean they have the same use case in JavaScript land.
@palyanytsia
@palyanytsia Жыл бұрын
Thank you for continuing making short videos
@gentlecoder5167
@gentlecoder5167 Жыл бұрын
So how do you do something like if (userFromServer.role === UserRoles.Admin) {doAdminStuff()} ?
@ariasalehi5665
@ariasalehi5665 Жыл бұрын
I think Enums are actually useful. I prefer this instead of an array : enum UserRoles { Null_User, User, Admin, Staff, } if you don't like the Null_User one you can use an object instead ( suggested by other comments )
@RamiroFarias1
@RamiroFarias1 Жыл бұрын
Or enum UserRoles { User = 1, Admin, Staff, }
@K38Media
@K38Media Жыл бұрын
He is correct that Enums aren't the best way to store data, but this also isn't the best example of how to properly use enums.
@animedreamz2009
@animedreamz2009 Жыл бұрын
In general you'd never try to iterate over an enum in let's say c or c++. It was not meant for that so you are correct in your usage but disingenuous by not including that you can set the initial options value to another number. In higher level languages it's kinda sugar for devs forms systems languages. It's like adding unions in JavaScript. It's useless.
@minikame2272
@minikame2272 Жыл бұрын
Thanks for the gift, finally, a YT link I can send the next time someone disagrees with me on Reddit over enums
@alinawaz4034
@alinawaz4034 Жыл бұрын
make more of these, I like them
@joshman1019
@joshman1019 Жыл бұрын
Changing a string literal value in one place might be a breaking change in 30,000 other places. But changing an enum's string initiation in one place will change it in all of the places it is used, and your developers will be able to more easily read your code.
@dzhimy6266
@dzhimy6266 Жыл бұрын
Not a typescript user or JavaScript, but in every other language you can explicitly set the values of enums, this is great for parsing binary protocols as you can do stuff like switch(bytes.peek() as enum PacketType){ case PacketType::A: break; case PacketType::B: break; ..etc.. } Where the bytes.peek() is returning some binary value like 0xEB, and perhaps in your PacketType enum defines PacketType::B as 0xEB like the following: enum PacketType { A = 0x42, B = 0xEB, … } Is this not a pattern that is possible in typescript? I imagine typescript’s enums are not so restrictive as to force enums to begin at 0 right? That kinda feels like a required feature all enums should have in every language, to be able to set a start value or just explicitly set every enum member value.
@benwyse
@benwyse Жыл бұрын
Thanks!!!!!!
@sdot0
@sdot0 Жыл бұрын
You can explicitly set the value in JS as well and they seem to be ignoring that in the video
@rentsy3444
@rentsy3444 Жыл бұрын
the solution is to not use enums in TS. A lot of languages the enums are hit or miss. Enums in Java are pretty good
@darialyphia
@darialyphia Жыл бұрын
export type Values = T[keyof T]; export const MyEnum = { FOO: 'FOO', BAR: 'BAR } as const; export type MyEnum = Values; You're welcome
@Mitsunee_
@Mitsunee_ Жыл бұрын
literally just put the word "const" before the enum keyword and now you keep the dot syntax but it's not a scuffed object anymore. I always use either `const enum` or `as const`, depending on if I need to iterate over the values (which I usually don't need if it's something I'd want to use an enum for) :)
@Spinikar
@Spinikar Жыл бұрын
Okay, so will admit I was really puzzled at first and was thinking this wasn't that big of a deal. I use Enums a lot and thought this was not that useful of a video, and that Enums are great and have been very useful, but after checking out the Video you recommended from Matt Polock, and deciding to pull back the layers of what TS is doing and what's actually happening when you're declaring an enum, I understand what you are getting at in this video. Just because something "works" doesn't mean that's a good way to do it, though also, if it does work, don't touch it. :) Anyone confused here, sure, you can use enum, obviously your code works, that's great, by all means keep doing you, but if you really want to improve, I suggest you pull back the TS layer and really dig into what's happening under the hood in JS. I'm looking at my Enums now a lot differently.
@ggascoigne
@ggascoigne Жыл бұрын
Numeric enums are legitimately problematic, but string enums just work as expected. Switching to bare strings loses the DX of having an easily accessible set of constrained values. I completely get the hate on numeric enums (and to be honest they can be problematic in other languages as well), but string enums, I'm still failing to see the real problem, and they offer some good benefits vs the alternatives. All of these issues would be solved with a lint rule blocking numeric enums.
@Szarlus
@Szarlus Жыл бұрын
How about const UserRoles = { User: "User", Admin: "Admin", Staff: "Staff" } as const type UserRole = typeof UserRoles[keyof typeof UserRoles] Then you get best of both worlds - not use enums and still get dot notation
@jesse9999999
@jesse9999999 Жыл бұрын
I have seen a lot of videos about typescript enums being bad recently, it seems to be the flavour of youtube at the moment, but they all seem to skip over the fact that you can assign your own numeric or string values to the enum. is there any reason not to do the below to solve the problem you're talking about here? For what it's worth, i think the type syntax with string literals is still a better solution, but I feel like assigning your enums this way avoids a lot of the enum problems I have been seeing on youtube recently. enum UserRole { User=100, Admin=200, Staff=300 } or enum UserRole { User="USER", Admin="ADMIN", Staff="STAFF" }
@ChillAutos
@ChillAutos Жыл бұрын
Any video that claims Enums are bad without addressing this is clearly just a quick clickbait attempt. How can you possibly state the issues, when you completely ignore one of the basic features of the enum. Its just an argument in poor faith, as you said he's just jumped on the Enum bad bandwagon like a few other youtubers, I respect the hussle but not his strongest videos and makes me question some of the other videos ive taken his word for irt topics I know less about.
@froxx93
@froxx93 Жыл бұрын
These new TypeScript features are lit. "as const", "satisfies", ... We're living in good times :') I just need to make me remind them when I need them.
@mickmister
@mickmister Жыл бұрын
Could you use an object instead of an array, then use `keyof` to declare the type? Then you could access like an enum, while also getting the type safety you're looking for. Also if I do use enum, I set the value like this to avoid the number issue: enum UserRole { Admin = 'Admin' } I prefer to use an object over enum so it can be used by js files if necessary. The array approach seems a little weird to me. I think I would prefer enum over that approach, using strings in the enum values of course.
@PhilipAlexanderHassialis
@PhilipAlexanderHassialis Жыл бұрын
Great, short and to the point Theo... but how about a followup with a enum UserRole = { User: USER, Staff: STAFF, Admin: ADMIN} with USER/STAFF/ADMIN being predefined const strings? If I recall correctly, past TS4.4. you can have this actually work for you in conditions and whatnot. P.S. Matt's video on enums was excellent. P.S.2: Who *in their right mind* actually do an if (an enum) and not if (check variable value vs enum)? Why are they allowed to do it more than once? :)
@omri9325
@omri9325 Жыл бұрын
if the property containing the enum is nullable maybe?
@t3dotgg
@t3dotgg Жыл бұрын
This is just string literal types with extra steps
@akbarnurullaev7918
@akbarnurullaev7918 Жыл бұрын
@@omri9325 I believe in a case of UserRole, it’s impossible that the property would be nullable :)
@PhilipAlexanderHassialis
@PhilipAlexanderHassialis Жыл бұрын
@@t3dotgg but but but my dot notation :)
@ametreniuk
@ametreniuk Жыл бұрын
Refactoring enums is still easier than string literals, although TS enums are a real pain in the ass. The module export problem with them blows me away
@ChillAutos
@ChillAutos Жыл бұрын
What's the module export problem?
@ambuj.k
@ambuj.k Жыл бұрын
Just so people know, it's not typescript's fault but the language it is built upon, javascript. We all know how weird javascript is, that's why we use protection such as typescript. So don't put a hole into that protection with a cool feature taken from other statically typed languages.
@maxz999
@maxz999 Жыл бұрын
Great video! Used AoC to learn some TypeScript and I probably used an enum on half of the days in AoC. This makes perfect sense to me though.
@modernkennnern
@modernkennnern Жыл бұрын
The only time I've used enums is in the context of using it in a c#-based backends with automated type generation. In C# an enum is always an int, so when we map it over its convenient also having an int so you can use it directly in the contract
@KiranasOfRizon
@KiranasOfRizon Жыл бұрын
UserRole.User is a value of type UserRole. It is not a value of type Boolean. The problem you are facing here is not with TypeScript having a bad enum implementation, but with TypeScript being backwards compatible with JavaScript, which has a notion of "falsey" and "truthy" values instead of a hard requirement on only using Boolean values inside of conditionals. If you wrote the equivalent code to what you have written here in Rust, it would fail to compile because it expected a value of type bool and instead got a value of type UserRole. Instead of asking "if (user.role)" you should be asking "if (user.role === UserRole.User)". And as for your suggestion to define types as a union of strings, that is fundamentally cursed. Strings are not for storing categorical data. It's a bad practice in every other language, and it's a bad practice in TypeScript.
@victortodoran1828
@victortodoran1828 Жыл бұрын
Reinventing a data structure because of a lose comparison that should have not be made in the first place
@benkogan1579
@benkogan1579 Жыл бұрын
Constant/nonconstant variants are the best way to go about enums in my opinion, like OCaml or Rust. Enums either don't have any value associated with them or they do, and it is never a surprise. Pattern matching also makes them much easier to work with, which JS unfortunately doesn't have.
@NuncNuncNuncNunc
@NuncNuncNuncNunc 10 ай бұрын
tl;dw Theo says don't use enums, create fake enums in a non-idiomatic way. Better: don't rely on default numeric enums. They are always a foot gun especially if they are getting set outside your code. Eventually someone will give you a bad value or somone will reorder the enums, or...
@eliberkowitz7454
@eliberkowitz7454 Жыл бұрын
Let's leave behind the strong clickbait opinions about how coders should develop behind in 2022. Generally, either string literals or enum with KEY = "KEY" both seem fine... String literals lose readability - `assign_role(user, "Admin")` is (imo) less readable than `assign_role(user, Role.ADMIN)` - is "Admin" a user-facing string? Typesafe? Part of some list of possible values? What is that list? They also sacrifice refactorability - good luck safely changing all occurrences of "Admin" to "SuperAdmin" in a large codebase. String literals are a bit easier to write since you don't need to import Role and you get autocomplete. But really, this is the kind of thing that just doesn't matter. There are some issues with string literals, and there are some issues with enums. Once you hit them once, you won't hit them again. Each developer/company has their own preferences that don't actually cause issues if stuck to consistently. And seriously, it's not like enums are a common source of bugs in any production code at least that I know of.. I don't know why it's become such a polarized topic lol
@jacobshore
@jacobshore Жыл бұрын
So. This is all avoided by initializing the first enum to 1. I'm not saying you should use enum. But seems simpler than the other solutions offered here.
@badazzmorris
@badazzmorris Жыл бұрын
Love these ❤️ more please 🙏
@umuden
@umuden Жыл бұрын
You helped me realise why many people dislikes me.. I also talk big about these kinds of "standard knowledge" or Elon Musk. I mean you shouldn't, in general, but some people know what they are talking about.
@gauravsingh1963
@gauravsingh1963 Жыл бұрын
Similar things can be said about javascript as a whole, it's more about knowing what works and what not. Have been using string enums for years in really huge codebases and never had any issues
@headlights-go-up
@headlights-go-up Жыл бұрын
Short TS videos are so nice. 11/10
@DrSystemAddict
@DrSystemAddict Жыл бұрын
For real though... I was afraid to click because I hate enums so much. Thanks for changing the thumbnail
@KarlOlofsson
@KarlOlofsson Жыл бұрын
Isn't this how you are supposed to use an enum with strings? I would agree that it's silly that it defaults to numbers so that you have to define it like this, but it does allow for the original syntax plus the dot-reference. enum Direction { Up = "UP", Down = "DOWN" }
@boredguy1663
@boredguy1663 Жыл бұрын
I mostly use enums to store repeated string values.
@Gobli8
@Gobli8 Жыл бұрын
This is such a bad take coming that enums are mostly used to improve readability when comparing roles/consts.
@gridlocdev2023
@gridlocdev2023 Жыл бұрын
I think the TypeScript static analyzer should make sure that developers aren't doing something incorrect like that if statement with enums. It simply doesn't make sense, it is checking a true/false state on the default value of an enum (the index of the enum itself) which hasn't been assigned a string literal or any boolean value. UserRole.User is a possible value for another value's state, NOT the state of a variable in and of itself. It's something that the C# compiler will warn you about, and C# enums work in the same way. The only reason this is passable in JavaScript (and not C#) is the semantics surrounding how JavaScript treats integer 0 and 1 numbers as booleans, and the index of the enum just so happens to be the same value of a JavaScript boolean.
@Ignas_
@Ignas_ Жыл бұрын
I would never use an enum (which is essentially a list of named integers in other languages) in a plain conditional. But if I really had no other choice, I would just do this: enum UserRole { Unassigned, User, Admin, Staff } It's really a matter of whether you know what you're doing or not, which I admit is much harder in JS. (Not sure if TS is any better at it)
@aundefined
@aundefined Жыл бұрын
This is the content I subscribed for 👏
@cauebahia
@cauebahia Жыл бұрын
Probably someone commented on this already. I agree with your point, but you should have mentioned string enums as well. What do you think about them? Thanks for the video!
@bsaravanaprakash
@bsaravanaprakash Жыл бұрын
enums are to define a static list of lookup items whose values never change. its subset to array containing static list of string literals. we use enums in java always and is much efficient than string array. define utility functions.. promotes single responsibility principle. maybe typescript hasnt matured enough to use enum efficiently.
@t3dotgg
@t3dotgg Жыл бұрын
Maybe you should watch the video
@euforic1
@euforic1 Жыл бұрын
You should check if it is the int value or if you really want you can add "default" for the first index of the enum and then your first item is > 0. I think that would be a much simpler usage. The problem is using a sudo typed language you can pick how type strict you want to be, which can be confusing to some.
@tedrose
@tedrose Жыл бұрын
enums in Typescript 😴 enums in Rust 😁
@kiboo1212
@kiboo1212 Жыл бұрын
I use string enums and never had a problem
@gamcd
@gamcd Жыл бұрын
Wow that first Enum example is wild lmao
@CatEngineDVD
@CatEngineDVD Жыл бұрын
You shouldn't rely on the boolean value of a numerical type either way though
@Xe054
@Xe054 Жыл бұрын
This is the first video by Theo I didn't understand. It would have helped if it was longer and went into more depth with the given example. What if you start the enum at index of 1? What does line 3 do? Are enums going to be deprecated or changed in the future?
@RohanBagchi
@RohanBagchi Жыл бұрын
I have seen a use of enums as constants. The alternative is a JS/TS object `const constants = { KEY: 'VALUE' }`. What do you suggest for these cases?
@nedgrady9301
@nedgrady9301 Жыл бұрын
Good trick and I agree in general. As always the real world sometimes gets in the way when numbers really are needed and there really are a set few described e.g. by a specification. Example web socket close codes - I found myself declaring this enum recently enum WebSocketCodes { NORMAL_CLOSURE = 1000, GOING_AWAY = 1001, PROTOCOL_ERROR = 1002, ... }
@mosescosme8629
@mosescosme8629 Жыл бұрын
THANK YOU. I've been thinking about this for months.
@yxngboypolo
@yxngboypolo 2 ай бұрын
He gave examples of bad coding, not an example of why enumeration is bad
@mosescosme8629
@mosescosme8629 2 ай бұрын
@@yxngboypolo what?
@yxngboypolo
@yxngboypolo 2 ай бұрын
@@mosescosme8629 the example he gave her horrible. All he did was show how not to code
@mosescosme8629
@mosescosme8629 2 ай бұрын
@@yxngboypolo why bother me about it?
@yxngboypolo
@yxngboypolo 2 ай бұрын
@@mosescosme8629 u made a comment approving his messages, I made a comment disproving yours. That’s how the Internet works buddy.
@benjaminfortune2707
@benjaminfortune2707 Жыл бұрын
How would one replicate enums that manage bit fields? E.g. Permitted login methods: `LoginMethod { None: 0, GoogleOIDC: 1, MsOIDC: 2, UsernamePassword: 4 }`, then writing something like `LoginMethod .GoogleOIDC | LoginMethod .MsOIDC`
@OldKing11100
@OldKing11100 Жыл бұрын
As a Python Pydantic fan I'm wondering how you feel about the Zod package. Getting Pydantic like validation in TS is a dream for a Python D4A specialist like me. For me it's always necessary to have an extremely strong validation library.
@BenMargolius
@BenMargolius Жыл бұрын
I think he’s a fan, it’s used pretty heavily in the T3 CLI
@oscarljimenez5717
@oscarljimenez5717 Жыл бұрын
Zod is amazing, in typescript we use it a lot. And in trpc, zodios or t3stack is default for everything.
@mosescosme8629
@mosescosme8629 Жыл бұрын
He's a fan. He covers it in his other Typescript video "You might be using Typescript wrong"
@dan-kn3dm
@dan-kn3dm Жыл бұрын
I find numeric enums useful when I want to retrieve the enum index number by using the enum itself. The suggested approach wouldn't work in this case without calling .indexOf on the array of strings every single time, which is wordier and less performant.
@t3dotgg
@t3dotgg Жыл бұрын
Using the indexes is even more cursed because you might add a new value to the enum and break the stored state
Enums considered harmful
9:23
Matt Pocock
Рет қаралды 203 М.
Heroku Is Dead, Here's What I Recommend
11:59
Theo - t3․gg
Рет қаралды 257 М.
Unveiling my winning secret to defeating Maxim!😎| Free Fire Official
00:14
Garena Free Fire Global
Рет қаралды 7 МЛН
ОБЯЗАТЕЛЬНО СОВЕРШАЙТЕ ДОБРО!❤❤❤
00:45
WHO CAN RUN FASTER?
00:23
Zhong
Рет қаралды 44 МЛН
The Joker saves Harley Quinn from drowning!#joker  #shorts
00:34
Untitled Joker
Рет қаралды 70 МЛН
The TRUTH About TypeScript Enums
12:04
James Q Quick
Рет қаралды 7 М.
If this ships, it will change javascript forever
25:54
Theo - t3․gg
Рет қаралды 201 М.
How to use TypeScript Enums and why not to, maybe
12:43
Andrew Burgess
Рет қаралды 18 М.
TypeScript - Enums: Обзор и когда не надо использовать
11:24
PurpleSchool | Anton Larichev
Рет қаралды 14 М.
WHY IS THE STACK SO FAST?
13:46
Core Dumped
Рет қаралды 148 М.
Naming Things in Code
7:25
CodeAesthetic
Рет қаралды 2,1 МЛН
I Cannot Believe TypeScript Recommends You Do This!
7:45
Web Dev Simplified
Рет қаралды 169 М.
This TypeScript Trick Blew my Mind
6:17
Josh tried coding
Рет қаралды 37 М.
8 Design Patterns | Prime Reacts
22:10
ThePrimeTime
Рет қаралды 404 М.
Unveiling my winning secret to defeating Maxim!😎| Free Fire Official
00:14
Garena Free Fire Global
Рет қаралды 7 МЛН