The Power of TypeScript Generics

Поділитися
Вставка

КОМЕНТАРІ • 30

  • @EpKjelltzer
    @EpKjelltzer Рік тому +30

    Can't you simplify the generic parameter here? If you instead specify that `T extends DropdownOption`, then you can say that options is of type `ReadonlyArray` and onSelect is of type `(arg: T) => void`. I believe this gives you the same type safety but with a simpler generic - which also means that the generic parameter of `Dropdown` can be simply `T extends DropdownOption`. I also think this expresses the generic constraint more clearly.

    • @andrew-burgess
      @andrew-burgess  Рік тому +4

      Yeah, you totally could! I like that simplification!

    • @covertgravy
      @covertgravy Рік тому

      W

    • @vikingthedude
      @vikingthedude Рік тому

      👑

    • @andrew-burgess
      @andrew-burgess  Рік тому +3

      Thanks Bush, I really appreciate your feedback! You're totally right, I am still learning, and I do try to ask for improvements from ya'll when I remember to. One of my favourite things about this community is how everyone is willing to share better ways to do things.

    • @glzr_io
      @glzr_io Рік тому

      @Cush but there literally isn't a way yet to de-duplicate generic parameters

  • @cyber-man
    @cyber-man Рік тому +4

    Really nice video, keep making them Love them :) it's cool not to have just beginner videos on yt, would be cool if you attach some screenshots of documentation when explaining stuff :) congrats on 10k!

  • @joostschuur
    @joostschuur Рік тому +3

    This is also a really good example of how to intimidate someone who just started using TypeScript ;)

  • @hugodsa89
    @hugodsa89 Рік тому

    Congratulations on 10k subscribers!! Been loving watching your content Andrew!

  • @georgel8651
    @georgel8651 Рік тому +2

    Nit: no need to assert `as const` for every `value` string in the `options` array; only the one after the entire array matters!

  • @erickmoya1401
    @erickmoya1401 Рік тому

    We just needed to know the parameters type, return type of our functions, and avoid "cannot find parameter x of undefined".
    Why is this in version 5.0?

  • @TheD0b1
    @TheD0b1 Рік тому +2

    Hey, try it:
    declare function Dropdown(props: {
    options: T[];
    onSelect: (arg: T) => void;
    }): void;
    Dropdown({
    options: [
    { value: "gadget" },
    { value: "widget" },
    { value: "foobar" },
    ],
    onSelect: arg => {
    console.log(arg.value)
    // ^? (property) value: "gadget" | "widget" | "foobar"
    }
    });
    Keeping benefits from pure JS and with all the power of Typescript - cleanest version in my opinion ;>

  • @macr76
    @macr76 Рік тому

    Really good content!

  • @OmarFKuri
    @OmarFKuri Рік тому

    Why not use `T extends string` and make DropdownOption a generic as well so that value is a string? Then you can remove all the `as const` calls from the array

  • @merotuts9819
    @merotuts9819 Рік тому +1

    Didn't know you could extract the type of an array element simply by accessing them with [] on type-level. I used to write my own cringe custom utility type for that 😅 Unpacked

  • @adambickford8720
    @adambickford8720 Рік тому

    This almost feels like leetcode but with types. Definitely cool and I learned a bit (T[number]? wtf?) but this would certainly not be the norm for application code.

  • @tito-ace
    @tito-ace Рік тому +1

    typescript is great but as a newbie this is pain in my brain :(

  • @TradingMotivation2
    @TradingMotivation2 Рік тому

    W video

  • @bolt6572
    @bolt6572 Рік тому

    cutie is back

  • @jasonlough6640
    @jasonlough6640 Рік тому +3

    yeah but... why?
    Ill number my arguments so all the comments can point out exactly where Im wrong.
    1) TS is mainly bloat. Look at all that extra code you had to write, which added significant mental overhead and slowed you down from delivering actual deliverables.
    2) Look at what youre doing before you even throw TS at it: that function Dropdown would never ever make it to prod written that way. It seems like youre applying the pojo pattern, in which case you probably want to Object.assign() all sorts of random crap (not just options or onSelect) to some constructed object, and pass that into DropDown.
    3) And the real killer for me is, these tutorials never have comments in them, comments which would handle 80% of any confusion TS tries to belay.
    4) The official docs even say to use it TS lightly and that it can be overly verbose.
    5) A decent set of unit tests are better than TS, and they dont get in your way as much, because you dont have to learn yet another opaque and broken language.

    • @joostschuur
      @joostschuur Рік тому

      Cognitive overhead was the first thing that came to my mind too. In this case, the typesafe benefits this results in don't feel like they justify making the code harder to skim/parse in my mind to me.

  • @mahadevovnl
    @mahadevovnl Рік тому +4

    Jezus, what a ton of code. It looks like it's over-engineered to hell and back, completely counter-intuitive. That T[number] thing is such a dumb syntax to begin with. Do you expect anyone somewhat new to TS to look at this and understand it? Ever?
    Just write:
    type TOptions = 'a' | 'b';
    type TDropdownProps = {
    options: { value: TOptions }[];
    onSelect: (arg: TOptions) => void;
    }
    const bla: TDropdownProps = {
    options: [
    { value: 'a' },
    { value: 'b' },
    { value: 'c' } // TS error
    ],
    onSelect: (arg) => {
    if (arg === 'a' || arg === 'b') {
    console.log('yay')
    }
    if (arg === 'c') { // TS error
    console.log('this can never happen')
    }
    }
    }
    So much simpler without all kinds of fancy TS magic. Very simply to understand.

    • @vytah
      @vytah Рік тому +2

      What if you want to have multiple dropdowns, each with completely different options? And in such a way that you don't need to repeat all the options in the type like you do?

    • @mahadevovnl
      @mahadevovnl Рік тому

      @@vytah Then you don't use TS to restrict the options, you use code. The options would simply be strings and there is no need to ever over-engineer it to that extent. It's insanely unintuitive.

    • @mahadevovnl
      @mahadevovnl Рік тому

      @@vytah Alternatively, you can have mutliple exclusive types, e.g.
      type TOptionsUser = 'a' | 'b';
      type TOptionsAdmin = 'c' | 'd';
      type TOptions = TOptionsUser | TOptionsAdmin;
      Force it like that. Don't over-engineer it.

    • @adambickford8720
      @adambickford8720 Рік тому

      @@mahadevovnl I think this is comparing a 'hard coded' solution that only works in this scope vs a 'parameterized' solution. Its simpler because its solving a simpler problem.

    • @andrew-burgess
      @andrew-burgess  Рік тому +3

      You've got some good points! Agreed, the T[number] syntax is too much.
      What I didn't explain very well is that if you have a few one-off cases, the generics approach is overkill; I would do something like what you did. However, if you're implementing a component system or library (even if it's just for other teams internally), this approach can give a really nice dev experience to the users of your component.