Are your TypeScript Unions broken? | Advanced TypeScript

Поделиться
HTML-код
  • Опубликовано: 5 июл 2024
  • Discriminated unions are one of TypeScript's most powerful features, and they become even more powerful when you learn about distributive conditional types.
    You can find a written version of this here: shaky.sh/ts-distributive-cond...
    My Links
    shaky.sh
    shaky.sh/tools
    / andrew8088
    #javascript #typescript #coding #programming
  • НаукаНаука

Комментарии • 35

  • @mettle_x
    @mettle_x Год назад +24

    5:51 You can write `K extends PropertyKey` instead of typing out `string | number | symbol` individually.

  • @dimitrimitropoulos
    @dimitrimitropoulos Год назад +24

    I'm glad to see you like the `T extends T` syntax rather than the `T extends any` variant. I 100% agree!

    • @alexismandelias
      @alexismandelias Год назад +2

      How is more clear than ???

    • @dimitrimitropoulos
      @dimitrimitropoulos Год назад +2

      ​@@alexismandelias to the uninitiated, both are confusing. I totally get that. The reason I find `T extends T` to be better is because triggering union distribution is the only use for that. Whereas sometimes you see people use `T extends any` in generic parameters (perhaps to get around JSX rule issues, but perhaps just while thinking through an issue before they put something better there (there's a typescript-eslint rule `no-unnecessary-type-constraint` for this)). Also the "similar but not the same" `T extends any[]` syntax is very commonly used for other purposes, but at a glance looks similar.
      With that context in mind, `T extends T` _only_ being used for this one thing is at least a little tiny bit easier because it's only got this purpose and this purpose alone.
      Does that make sense? I've been thinking of making a video on the Michigan TypeScript channel to discuss this literal topic of one versus the other (just for fun), so I'd love to hear your feedback.

    • @Micha-ohne-el
      @Micha-ohne-el Год назад

      I would personally prefer `T extends any`, because I know exactly what it does, at a glance. I know for certain, from all my TypeScript experience, that `any` covers all types. For the `T extends T` syntax, I would have to know if *every* single type extends itself. Which I don't. I mean, it seems straight forward, but doing `x === x` seems straight forward too, and that does *not* return true for every value (it's false for `x = NaN`). So I kept thinking if there was a type that somehow didn't extend itself, for some weird reason. Maybe `null`? Or maybe `never`?
      If I stumbled across `T extends T` in some codebase, I would 100% have to google what it does, but `T extends any` is obvious. And if you really hate `any` that much, you can always write `T extends unknown`.

    • @at-2974
      @at-2974 Год назад

      T extends T makes perfect sense if you think of it as the identity of T.

  • @dealloc
    @dealloc Год назад +4

    On top of this, if you want to simplify the type, so instead of seeing "Omit | Omit", is to reconstruct the type which can be done generically like this:
    type Simplify = { [P in keyof T]: T[P] } & {};
    The "& {}" at the end is key here. You could also replace it with a "[][0]" if you wanted. The idea is just to tell TypeScript to create a new type from it rather than trying to be smart about it.

  • @MrREALball
    @MrREALball Год назад +3

    Wow! Finally something useful that I didn't know about typescript. Great video, great explanation.

  • @vieruuuu
    @vieruuuu Год назад +1

    Haven't thought about using extends, what I found works is using a mapped type to iterate a union
    type A = { [ member in Union]: Array }
    type B = typeof A[number]
    I find it a bit more verbose.

  • @NerveClasp
    @NerveClasp Год назад

    OMG! I think I've faced similar issue too many a time in my work, I'll have to check tomorrow.. Thanks a million!!

  • @PfalzerGbr
    @PfalzerGbr Год назад +1

    Oh nice! Just hit this issue last Friday, wasn’t sure what’s going on.
    Makes a lot of sense now. Thanks, you just saved me a ton of boilerplate!
    Awesome channel by the way, this is the kind of in depth content we miss :)

  • @SoreBrain
    @SoreBrain Год назад +7

    Great content I really like where this channel is going. One thing I would have liked would have been one more application example or use case. Also when there were all the different but similar types listed, a comment above each showing their type signature for an easier overview.

    • @andrew-burgess
      @andrew-burgess  Год назад +1

      Great feedback, appreciate it! Thanks for watching!

  • @pedrotorchio
    @pedrotorchio Год назад

    Dude, this is awesome. Glad I found your channel. Please continue with advanced/niche(ish) typescript features. I feel like very few people actually have access to this kind of information through typescript docs and forumns.

  • @cyanoswag
    @cyanoswag Год назад

    Really good video, thank you. I like your content - concise and helptful.
    Also, 10K subscribers ftw!!!

  • @AlexFeature
    @AlexFeature Год назад

    I was very fortuante to find your channel a few days ago. I'm trying to teach myself Angular and apparently NG and TS are like best friends or something. The way you present the material is just spot on.
    Comming from C# background this stuff just blows my mind, I used to always make fun of JS for its quirkiness but I have to say TS type system is pretty incredible. Thank you for doing an awesome job with these vids!

  • @offroaders123
    @offroaders123 Год назад

    It's great when RUclips/content creators do this; I discovered this would be perfect for my project late last night. Then I woke up this morning, and this was one of the first things in my recommended feed. Super cool! Sometimes the 'idea stars' line up, it seems like 😆

  • @AC-cd4vv
    @AC-cd4vv Год назад

    This channel always produces quality content

  • @ChesterRivas
    @ChesterRivas Год назад

    Great video Andrew.

  • @codingroom928
    @codingroom928 11 месяцев назад

    i failed to understand fully but i helped a lot to make a my typescript working. thanks

  • @siulingding73
    @siulingding73 Год назад

    this was nice, thanks for the vid!

  • @FlyingPenguino
    @FlyingPenguino Год назад

    Learned something new - thanks 💪💪

  • @vikingthedude
    @vikingthedude Год назад

    Happy for you bro

  • @KirkWaiblinger
    @KirkWaiblinger Год назад

    Seen unions so many times I'm starting to pronounce it like onions in my head

  • @sebabatsomashego7988
    @sebabatsomashego7988 Год назад

    What is this declare keyword he used

  • @lucasyuri5385
    @lucasyuri5385 Год назад

    Why this is allowed:
    export interface IUserAccessMFAActivation {
    access_token: string;
    mfa_activation: boolean;
    }
    export interface IUserMFARequired {
    mfa_required: boolean;
    mfa_nonce: string;
    }
    type IUserShopAuthResponse = IUserAccessMFAActivation | IUserMFARequired;
    function test(): IUserShopAuthResponse {
    return {
    mfa_nonce: 'aa',
    mfa_required: true,
    access_token: 'aa',
    mfa_activation: true,
    };
    }
    The function should complain about the return, I want to be allowed only to return:
    {
    access_token: string;
    mfa_activation: boolean;
    }
    or
    {
    mfa_required: boolean;
    mfa_nonce: string;
    }
    can i fix it with distributive conditional types?

  • @Brunoenribeiro
    @Brunoenribeiro Год назад +1

    I really like what TS is bringing to the web, and what the community is building and teaching with it... but this is so hackish 😑 makes me wonder why there's no built-in support for this.
    (Awesome video nonetheless, it was cool to learn this)

  • @PedroSanchez-od7cc
    @PedroSanchez-od7cc Год назад +1

    I already know typescript sucks,
    you don't have to sell it to me.

  • @helleye311
    @helleye311 Год назад

    I wish I found this channel sooner, about 3 weeks ago I ran into this exact issue. StackOverflow helped by providing something akin to your DistributedOmit, but it would have been nice to just know how this works.

  • @NezNez
    @NezNez Год назад

    I didn't knew that `boolean` is treated as a union of true and false! that was new for me!
    type UnwrapUnion = T extends T ? Array : never
    type BooleanArr = UnwrapUnion
    ^ true[] | false[]

    • @andrew-burgess
      @andrew-burgess  Год назад

      huh, very cool, that's not what I would have expected. Thanks for sharing!

  • @i.j.5513
    @i.j.5513 Год назад

    ninja 🥷