The TRUTH About TypeScript Enums

แชร์
ฝัง
  • เผยแพร่เมื่อ 29 ก.ย. 2024

ความคิดเห็น • 68

  • @hank9th
    @hank9th 2 หลายเดือนก่อน +3

    When your Enum is backed by data in a DB, I've found that using "pojo as const" isn't quite as nice of an alternative.
    For example, I have "UserRoles" represented in my DB as 1-indexed integers, and find that using an enum backed by 1, 2, etc. is a very convenient way to reference those db values in my code in a very human-readable way.
    Using ints also allows me to sort my roles hierarchically and perform gt/lt comparisons which I wouldn't be able to do with pojo as const. I can also quickly rename any of my roles in code w/o needing to do a db migration.
    All that said, I am relatively quite new to TS as compared to other languages, so there may be a better way to achieve what I want w/o enums. If anyone has suggested alternatives I'd be happy to hear them!

  • @jvdl-dev
    @jvdl-dev หลายเดือนก่อน

    I think there's definitely a case for both. One benefit of using a POJO is that, particularly for a library, you may want your consumers to just pass in a string value rather than also needing to import the enum and using that. Overall more flexible in that regard I think.
    I'd also add that when I use enums, they're always fully defined with explicit value, I don't want automagic values in there because those automatic values are bound by their order, so if you re-order the keys in your enum, but were expecting an index value in a different system (e.g. when sending serialised data), then you'll end up with problems the type system can't help you with.

  • @dkazmer2
    @dkazmer2 6 หลายเดือนก่อน +11

    Based on Matt's video, I've already made the transition to POJOs. I like the flexibility of hardcoding strings, while still getting error checks and intellisense

    • @JamesQQuick
      @JamesQQuick  6 หลายเดือนก่อน +4

      Fair enough. Just not the way I think about it. Glad that's working for you!

  • @snatvb
    @snatvb 6 หลายเดือนก่อน

    Easy to use:
    const roles = {
    admin: 'admin',
    user: 'user',
    } as const
    type Role = ValueOf
    declare type ValueOf = T[keyof T];
    I have no idea why you need "enum"
    If you will have library enum and codegen enum(from prisma / gql for exmaple) and they will be identity or one of the options would be more of a narrow type, they'd all be incompatible
    do you know how devs fix it? just cast, nice "safety" method (nope)
    Nobody must use enums, it must be removed

  • @glitchinLife
    @glitchinLife 5 หลายเดือนก่อน

    I see your point, and I agree that most of people wouldn't be able to understand Matt's alternative (yet produce it, or even use it effectively in a codebase). But at the same time I think it's important to point out few things.
    1. The use of reverse mapping is beyond just calling a method with a string where we should've used the enum, it's the ability to get the enum from a string (e.g. you have an error status code, and you want the get the enum from it. Or you have string file names and you want to get the enum for the extensions ...).
    2. Why enum in general feels "odd" in the world of TS is because they behave differently. TS type system is based on the "shape" of the objects, (i.e. if object A is of type Person, and object B is of a type that fits the description of a person, then we can use B where we used A and viceversa). You cannot do that with enums as Matt explained, and that's enough reason for me to at least try to avoid them when possible, specially for TS newcomers because it will confuse them.
    With that said I loved the video, and I loved how you respectfully shared your opinion while giving credit to Matt 🎉

    • @JamesQQuick
      @JamesQQuick  5 หลายเดือนก่อน +1

      Thanks for watching and sharing your thoughts! :)

  • @omarramoun3380
    @omarramoun3380 5 หลายเดือนก่อน

    i like your critique. it was really eye opening. you answered a lot of the questions i had after watching his video. thanks.

    • @JamesQQuick
      @JamesQQuick  5 หลายเดือนก่อน +1

      Wow, so glad to hear that! Thanks for wathching!

  • @Stoney_Eagle
    @Stoney_Eagle 6 หลายเดือนก่อน

    I respect Mat's wisdom on typescript, but I am team Enum.
    I love the strictness, though I also use the "POJOs" it just depends on how I want to use something.

  • @christopheanfry2425
    @christopheanfry2425 6 หลายเดือนก่อน

    I think this is the problem of typescript and JavaScript in general to always add different rules and work around that lead to misunderstanding and always provoking feelings of skill issues. Getting some interest to strict typed languages you realize that these native features are working as expected you have to learn how and when to use them. Enums are great and following the typescript documentation they have to be used in a certain manner. Great video

  • @airbornesnail
    @airbornesnail 6 หลายเดือนก่อน +1

    Seems like Matt is forgetting the sole purpose of typescript sometimes. Thanks for the heads up, James.

    • @HoNow222
      @HoNow222 6 หลายเดือนก่อน +1

      YEAH, Matt and other "typescript masters" or whatever the hell they are called are 100% using typescript for the only sake of typescript itself, like using english language to write a poem. But we use typescript to make programs do stuff lol, and James take here is much more honest and practical

    • @traviswaithmair4809
      @traviswaithmair4809 6 หลายเดือนก่อน

      TS currently follows a “duck typing” system. ie if two types are the same you can use them in place of each other. TS also has a philosophy of having TS disappeared in transpilation or in other words TS shouldn't leave code artifacts behind. Enums are the exception to this because it was early in the TS life and these philosophys hadn't been added.
      Matt and others like him advise against Enums because they go against the grain of TS in its current state

  • @alfrodo_perez
    @alfrodo_perez 6 หลายเดือนก่อน

    Enums❤

  • @__azt
    @__azt หลายเดือนก่อน +1

    I actually agree with you more on these points. When we write enums, we're signaling to the reader that these values come from a predefined, limited set.

  • @Arcwise
    @Arcwise 2 หลายเดือนก่อน +6

    If devs are calling object methods on enums or try to circumvent them by passing hardcoded values instead, they have missed the point of enums. Any unexpected behavior that arises from such misuse is not the language’s fault.

  • @bryson2662
    @bryson2662 6 หลายเดือนก่อน +4

    Pocock's magic typescript is just using a keyof operator which every typescript dev should use.
    I think the disagreements about being able to use strings instead of enums is a good consideration but just a preference and depends on what you're trying to do in the code

  • @simasbutavicius8485
    @simasbutavicius8485 6 หลายเดือนก่อน +5

    Great point at 8:33 . Sometimes you work with javascript codebase and people whom you try to convince to switch to Typescript. The simpler the better in those cases. It all depends on context.

    • @VladyslavAvidzba
      @VladyslavAvidzba 4 หลายเดือนก่อน +2

      the point is basically 'i am dum dum, so as const is bad and enums are good'
      and don't talk to people who need to be convinced to switch to TS in 2024. These are dinosaurs

    • @nadavzeira389
      @nadavzeira389 2 หลายเดือนก่อน

      ​@@VladyslavAvidzbaBS.
      Of course TS is excellent, but there are also alternatives and cases you don't have to require type safety. Just like in plain-old Python, for example.
      Also, your first point is also dumb, because that's not the reason people defend Enums.
      Once you define values in an Enum, it is basically the same thing as POJOs, just without ther overhead of writing types to get the POJO's keys/values type.

  • @dustatron
    @dustatron 6 หลายเดือนก่อน +2

    I like both. I don’t feel like enums deserve all the hate. I can say I have ran in to edge cases with both that I found frustrating. So I tend to use an enum if I am going to build tightly coupled components and I don’t intend to share the enum around my app or apps. I use the as const if I’m building something that needs to be more generic and can be shared and reused all over.
    But per your comment in the video. If the intent is to have teammates use exact strings that I know might change I think the enum is the right tool.

  • @JanisWalliser
    @JanisWalliser หลายเดือนก่อน

    I think what really comes into play here is your background. If you come frome an OOP background (like Java) you probably really want to always pass it like you said (ENUM.ATTRIBUTE). But if you come from a JavaScript background I think you might have another mental model where TypeScript is not OOP in JavaScript but instead just forces you to pass the right things and you might prefer that you are able to pass the values instead of ENUM.ATTRIBUTE as well. Because for example you could define a type have that type as a paramter but you dont have to ACTUALLY pass that type. You just have to pass something that looks the same as that type. E.g. you can make two type aliases that define the same object and use them interchangebly throughout the code. That is not what someone coming from OOP would expect but it is how TypeScript works. So "Matts Enum" is more in line with that.

  • @codewithguillaume
    @codewithguillaume 6 หลายเดือนก่อน

    Oh James ! There's a real topic around Enums. I really doubt about using them! Prefer to use types and typeof

  • @azizsafudin
    @azizsafudin หลายเดือนก่อน

    The first example in your tweet makes no sense if you’re only using those strings within className? Why not make a specific tailwind class with those sizes?

  • @mrst8086
    @mrst8086 4 หลายเดือนก่อน

    Lol just checked, it works this way with ANY NUMBER:
    enum A { one: 12, two: 345 } ==> ["one", "two", 12, 345]

  • @sify11
    @sify11 หลายเดือนก่อน

    in every legit language enums get numeric indicies to store the information in lesser memory units. it IS what i would expect of an enum. it's js thats 💩

  • @mohsinammar5070
    @mohsinammar5070 3 หลายเดือนก่อน +1

    4:34 If you're working in a company like mine where you have like 20+ packages, this can get really cumbersome. We have rules to not import from the src directory which means all the enums you use for a component property in a package need to be exported explicitly. Often when someone else builds a package you're using and for example, you're trying to inherit a type(with enums) from it, it can be so problematic because that enum has to be exported explicitly while union with values solve so many of these issues.

  • @AnthonyPaulT
    @AnthonyPaulT 6 หลายเดือนก่อน

    There is nothing wrong with passing nromal strings if everything is typed correctly. That's the whole point of TS. Not sure what you point was in 4:45min. TS will check the value itself if you type it correctly, so there is no problems there. I stopped watching, i should start making videos honestly...

  • @skylerdjy
    @skylerdjy 6 หลายเดือนก่อน

    I just don't see any valuable reason to use enums over type literals or objects except when it comes to log levels examples.
    People usually use enums for values that aren't supposed to change or to avoid typing the same string all over the codebase in case they need to change it. And that's my biggest issue with enums is that they allow you to change their underlying value and typescript will think everything works as expected. It's especially worse for DB related stuff because the underlying value should never change and get out of sync with your db.
    Just found this issue in our api a few weeks back. I'd much rather hardcode strings and rewrite the same string in multiple places and get a typescript warning all over the codebase when someone tries to change that value as opposed to enums saying everything is fine. It's too easy for a dev to come and change the values of the enum due to whatever reason and not realize that this value is how it's stored in the DB and lead to all sorts of issues.

  • @cgh2467
    @cgh2467 6 หลายเดือนก่อน +1

    Regular ENUMS as you have used is 100% the way to go.
    For me this removes the need for hard coding strings.
    If you haven’t worked in a large repository before you don’t know how bad hard coded strings can be especially when refactoring.
    Plus the example with POJOs is simply more code to get the same functionality from a traditional enum using a key and value.

    • @JamesQQuick
      @JamesQQuick  6 หลายเดือนก่อน

      Thanks for sharing your thoughts!

  • @MrAlao675
    @MrAlao675 6 หลายเดือนก่อน +5

    I've been using POJO and always will.
    I like simplicity 😅

    • @aestheticallyamazing2003
      @aestheticallyamazing2003 6 หลายเดือนก่อน

      What is pojo?

    • @MrAlao675
      @MrAlao675 6 หลายเดือนก่อน

      @@aestheticallyamazing2003 Plain Old Javascript Object

    • @mehmetyalvac7338
      @mehmetyalvac7338 6 หลายเดือนก่อน +1

      Plain Old Java Object?

  • @deatho0ne587
    @deatho0ne587 6 หลายเดือนก่อน

    I like Matt's version but comment it do to I underestand it is hard to understand.
    If you want to just use a key and the value does not need to be different can use an array as const with a bit of TS.

  • @aleksandarpopovic3615
    @aleksandarpopovic3615 6 หลายเดือนก่อน +1

    I watched it before Matt's video, with as const another set of problems opens up :D,
    something like this Array of Foo not assignable to Readonly Array of Foo
    so I use both things interchangeably
    enum Status { Close = 0, Open = 1 ...etc}
    I have a lot of things stored in the database like this as a integer

  • @Vladyslav85
    @Vladyslav85 6 หลายเดือนก่อน +1

    Getting to a point (with TS) when i need to rename keys, cascade from one type into a new type or other advance TS, in my humble opinion means you didn’t do your stuff right from start and when i say start, i mean diagrams, scenarios, before first line of code.
    Beside this, have one of “Matt” in team, with his advance TS level will only get latency on development, lets not forget for what TS is made: enforce addresses to accept type, avoid js dynamic type.
    Or maybe im wrong 😑
    Oh and beside this, “as const” beside making it readonly, you can use it as type, the type being the literary value not type of const value. Basically another kind of Enum with keys value defined.

  • @danandreev6673
    @danandreev6673 หลายเดือนก่อน

    For me the only reason to use enums is Data Base, I wan't to restrict the column values to a set of strings (or numbers). Other than I either use a POJO or a string type (type MyString = 'foo' | 'boo')

  • @cas818028
    @cas818028 6 หลายเดือนก่อน

    Same guy that wrong c# wrote typescript. Enums are a staple of c# they are a value type and work the same way. Typescript isn’t applied when you reading PRs from GitHub. Being able to quickly distinguish between strings and Enums is very valuable. To many things look like a hard coded string in JS/TS

  • @mudyeet_
    @mudyeet_ 6 หลายเดือนก่อน

    I've used both kinds probably just as much as the other, and I honestly think if you're looking to make something rigid, go with Enums, they are simpler to define, and there's only one way to use them so there will be consistency in the code. Freedom sometimes takes away the consistency imo.

  • @firewatermoonsun
    @firewatermoonsun 2 หลายเดือนก่อน

    I wonder in const a = {name:"Peter") as const, why use "as const" if it is already assigned to const a?

  • @marcush3997
    @marcush3997 6 หลายเดือนก่อน +6

    I could be wrong but using “as const” object as alternative to Enum isn’t new and is a widely used typescript pattern. So personally I don’t see why it’d cause confusion. And this pattern is even mentioned as alternative in modern typescript in the typescript official documentation under the Enum section.
    My personal preference is to stick with object because it’s predictable vs you get so many quirks with Enum.

    • @JamesQQuick
      @JamesQQuick  6 หลายเดือนก่อน +1

      I'm not saying "as const" specifically causes confusion. I think the TypeScript that comes with it to get typings adds some confusion though. Regardless, I agree, it's a perfectly valid way to do this

  • @roobannadarajah7989
    @roobannadarajah7989 6 หลายเดือนก่อน

    Oh man , i had always in this mind why enums are so compliacted in typescript. i also think same as you

  • @wchorski
    @wchorski 6 หลายเดือนก่อน

    why not use JSON for 'fake database data' and ts Types for intelesense?

  • @Kushagraa
    @Kushagraa 6 หลายเดือนก่อน

    I've a pretty nice example for the last plain javascript part, I'm in a situation where i need types value in booleans with associated name for developing. tried to use enums but it does not infers into booleans. I can use this as const method to declare types of " transaction = { Debit : true } " that made it pretty easy.

    • @nadavzeira389
      @nadavzeira389 2 หลายเดือนก่อน

      Well, that's not really the use-case for Enums anyways, so of course Enums won't work. Pretty sure Enums in any language don't support this use-case.

  • @jainebri
    @jainebri 6 หลายเดือนก่อน

    What is the name of the extennsio that shows online values when you are writing??... it is nice ..

  • @fluntimes
    @fluntimes 6 หลายเดือนก่อน

    Ever since I have discovered as const, I can't really go back to enums. I have used them before, but moved over to using string unions instead. The downside of unions is the inability to iterate over them, hence as const is a nice way of solving all the issues and limitations of enums and alternatives.

    • @JamesQQuick
      @JamesQQuick  6 หลายเดือนก่อน

      Nice! Glad you found something that works.

  • @kettenbach
    @kettenbach 6 หลายเดือนก่อน

    Excellent topic and great counterpoints. Aside from the weird index thing, I agree with you that they behave exactly as I would expect them to with no added complexity. Yeah Matt is the 🐐 for Typescript. 💪

    • @JamesQQuick
      @JamesQQuick  6 หลายเดือนก่อน

      Agreed on both points! lol

  • @jlmx
    @jlmx 6 หลายเดือนก่อน

    Great vid. I think you already know my take on this. 😅 I'll just mention that to me, avoiding usage of something because some people may not be familiar with it isn't necessarily a reason to avoid it. There's plenty of features in languages that are there for a reason even if we don't reach for them often. That said I agree that the end of the day it really doesn't matter *that* much which one you use, as long as it works well for you and your team.

    • @JamesQQuick
      @JamesQQuick  6 หลายเดือนก่อน +1

      Yeah I agree with that as well. It's not the specific reason I'm choosing not to, just something worth noting. Thanks for watching and sharing your thoughts!

  • @thescotsmav
    @thescotsmav 6 หลายเดือนก่อน

    Great vid.
    Would I use Enums or 'as const objects'? I think the answer as always is "it depends". But I do tend to lean a bit more towards objects than enums. My main reasoning being objects are JS native and transpile predictably, while enums are purely TS and can do the weirdness with keys etc that you both describe.

    • @JamesQQuick
      @JamesQQuick  6 หลายเดือนก่อน +1

      Thanks for sharing. I question the "JS Native" part simply because of the other TypeScript lines that are included after the POJO. Also "as const" is TypeScript not JavaScript. So you still have transpilation going on for the majority of that code lol

    • @thescotsmav
      @thescotsmav 6 หลายเดือนก่อน

      @@JamesQQuick ​ That's fair. I was meaning more the concept of objects vs enums in JS. With the TS after the POJO informing the linting/typechecking, rather than being code that is run.
      But, you're right. The 'as const' isn't JS, and the same with the additional TS lines after the POJO. Which does mean there's transpilation, the 'as const' and typedefs are stripped (though I could be wrong on that). In my opinion that is more predictable than to an IIFE that may, or may not, add additional keys depending on whether string values are used.

  • @joedparin354
    @joedparin354 6 หลายเดือนก่อน

    i want to minimize imports like importing enums

  • @theLowestPointInMyLife
    @theLowestPointInMyLife 6 หลายเดือนก่อน +2

    I would never use object.keys on an enum, never even ocurred to me that you could because I wasnt thinking of them as an object, I also agree that the entire point of using enum is to avoid hardcoded strings
    matt pocock might know a lot about typescript but what software has he actually built?

  • @antonarbus
    @antonarbus 6 หลายเดือนก่อน +1

    switching from "as const" to "enums" after your video, enums look simpler

  • @cas818028
    @cas818028 6 หลายเดือนก่อน

    Fight the system! I stand with you ! Enums are great!

  • @AlainBoudard
    @AlainBoudard 6 หลายเดือนก่อน

    Totally love your points here, makes so much sense to me, and it's really how I use enums in Angular. Once the surprise passed that, ok, we should always give values to our enums, then you can get rid of all the strings parameters in many places, and I think it does serve its purpose.
    And also, totally agree, Matt level is so high, I can't produce that kind of code without serious hints.
    Anyway, thanks James, fuel for thought 💪🙂

    • @AlainBoudard
      @AlainBoudard 6 หลายเดือนก่อน

      Also, the argument about the "readable values" doesn't make too much sense to me, since I often work with i18n apps, and I don't want to ever think that enums contains anything other than keys.