No BS TS #4 - Function Overloading in Typescript

Поділитися
Вставка
  • Опубліковано 22 жов 2024

КОМЕНТАРІ • 118

  • @mellow-meanderings
    @mellow-meanderings 3 роки тому +33

    you're an amazing educator Jack! i love how you explain the concepts in depth but also bring up the simple things like what is unknown, when it become contextually necessary.
    SOO much better than some other tutorials just blurting out every thing with no context because the way you teach things actually sticks!!!

    • @jherr
      @jherr  3 роки тому +10

      Thank you so much for that. I really appreciate it. I genuinely do try to structure stuff in a way where it's relevant and accessible, and hopefully sticky like that.

  • @slikk66
    @slikk66 3 роки тому +17

    this series is gold, great content

  • @floofthefops
    @floofthefops 2 роки тому +1

    This has to be the best and easiest to understand series. It also goes deeper into actually implementing useful stuff. Thank you

  • @8koi245
    @8koi245 Рік тому +1

    Loving it, I went a little beyond and figured out that if we get arg2 it'd be number so I did that and indeed worked just fine!

  • @geneartista9714
    @geneartista9714 2 роки тому +2

    Thanks for taking up your expensive time to create us these good tutorials.

  • @ronniecorbett
    @ronniecorbett 3 роки тому +38

    Great channel Jack!
    You could use keyof to avoid a hardcoded type -> coord[key as keyof Coordinate] = parseInt(value, 10);

    • @jherr
      @jherr  3 роки тому +8

      Nice! We actually will be covering `keyof`, but for some reason I didn't think of using it here. Nice catch!

    • @anshikgupta2993
      @anshikgupta2993 2 роки тому

      key as 'x' | 'y' really confused me. Can you explain how it resolved the issue?

  • @MrWickedsouls
    @MrWickedsouls 2 роки тому +2

    "Feel free to share with your friends" Coders don't have friends, and if they do, they wont understand Overloading. Great video!

  • @lifeok6188
    @lifeok6188 3 роки тому +5

    Nice setup with perfect light 👍. Jack is becoming younger day by day 💪 😎

  • @3DPTR
    @3DPTR 2 роки тому +2

    I love these videos , I try to watch one every day because those are sensible concepts about TS , I would like to know them by heart ! thanks Jack!

  • @Moonwalkerrabhi
    @Moonwalkerrabhi 3 роки тому +1

    These videos should have like 50x more likes and comments than they are , this is pure gold content

    • @jherr
      @jherr  3 роки тому

      Thank you!

  • @juhandvan
    @juhandvan 2 роки тому +1

    The example is very simple to get it. Thank you so much, Jack

  • @alanshortis958
    @alanshortis958 2 роки тому +7

    A small change I made after some googling: instead of repeating the valid keys as `coord[key as 'x' | 'y']` you can define a new type for valid keys in the Coordinate interface: `type CoordKeys = keyof Coordinate`, then use it as `coord[key as CoordKeys]`.

  • @abdellahcodes
    @abdellahcodes 3 роки тому +3

    Jack posts. I watch. That simple.

  • @fares.abuali
    @fares.abuali Рік тому +2

    Thank you so much!
    This is very useful

  • @sonalkumar702
    @sonalkumar702 2 роки тому +1

    No BS you are very good at explaining thing.

  • @jeremythompson8697
    @jeremythompson8697 9 місяців тому +1

    Hi Jack, this is great - especially for multi-lingual programmers. I've got a question, this overload function parseCoordinate(obj: Coordinate): Coordinate; - you declare the "let coord = 0 ,0" and you return that, however when I call the parseCoordinate with a Coordinate it simple returns what I passed in by ref. And in the overload implementation there is no way to access the obj argument, "Cannot find name 'obj'". So how does it magically assign coord = obj; ? Thanks appreciate your time and effort!

  • @ram-bk4mu
    @ram-bk4mu 3 роки тому +1

    This is great! I have watched many videos of TS but nothing like this!! thanks a lot!

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

    I love how you teach such advance and complex data manipulation and structing a really nice code
    Love From Pakistan♥❤❤

  • @mandihaase2744
    @mandihaase2744 2 роки тому +1

    These videos are incredibly helpful! Thank you so much for all the work you do to help the developer community~

  • @josemfcheo
    @josemfcheo 3 роки тому +1

    Awesome videos, I'll gonna start to share this channel with my friends

    • @jherr
      @jherr  3 роки тому

      Fantastic! Thank you!

  • @Fullflexno
    @Fullflexno 3 роки тому +2

    Thank you for providing so much good information. Cheers from Norway. I love your teaching style! «cool»
    Again thank you!

  • @fernard8985
    @fernard8985 2 роки тому +1

    Hi Jack, in the last example, i think coord[key as keyof Coordinate] looks pretty neat too.

    • @pooyaestakhry
      @pooyaestakhry 2 роки тому

      I guess it was better to check whether it's (x | y) or not by an if block, cause there might be an error while sending those coordinates. Also i would trim the strings.

  • @okerror1451
    @okerror1451 3 роки тому +1

    Whoa, I had totally missed that overloading was possible in Typescript.

    • @jherr
      @jherr  3 роки тому

      Possible-ish. It's not the same as a C++ or Java.

  • @yosha2467
    @yosha2467 3 роки тому +8

    Just a slight error fix for 5:35 there is no such thing as type casting in TypeScript, 'as' is type assertion which basically says "I declare that this is whatever I say it is" making the compiler raise its hands and just assume that what you wrote after 'as' is true.

    • @jherr
      @jherr  3 роки тому +2

      You are correct, it's not a runtime coercion.

  • @nickwoodward819
    @nickwoodward819 2 роки тому

    Hi Jack. Great video again, thanks!
    Quick question if you don't mind. I had thought 'as Type' and '' would be interchangable - and they seem to be, until @8.05, when you type `(arg1 as string).split()`.
    `arg1.split()` doesn't work in its place, but assigning it to another variable `const arg = arg1; ` then calling `arg.split()`, does work, and I was just wondering why?
    Thanks!

  • @william3588
    @william3588 3 роки тому +6

    Pure awesomeness

  • @darkmift
    @darkmift 2 роки тому +2

    As overloading is not native to js this was interesting to learn as a concept.
    I feel however this may be something to be avoided in practice due to the potential confusion a function with several implementation may lead to.

    • @jherr
      @jherr  2 роки тому +1

      IMHO, overloading is mostly about legacy library support.

    • @nickwoodward819
      @nickwoodward819 2 роки тому

      If all the declarations are next to each other would it really be confusing? Surely it's like saying overloads would cause confusion in Java? Developers know they exist in TS, just as they would in Java.
      Just my 2 cents, but everytime I hear this as a reason not to use them I hear "this isn't javascript". Which is surely the point! :)

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

    Love your content. I would've parsed the string with regex rather than the multiple splits.

  • @NuncNuncNuncNunc
    @NuncNuncNuncNunc 2 місяці тому

    Found this late, but type coercion using 'as' is almost always a warning that something is not right. Type guards that introspect the arguments and tell the compiler that the value is safe to use as the desired type offer much more protection.
    For example, in the example code passing any object to parseCoordinate, such as { name: 'typesafe' } will return that object to callers and be treated as if it had x and y number fields resulting in a runtime error in this case.
    Another example, let a = parseCoordinate({ x: '1', y: '2' }). If you have a sum coordinates method taking two Coodinates and pass it a for both you will get an object, { x: '11', y: '22' } that the compiler still thinks is a valid Coordinate.

  • @yt-1161
    @yt-1161 Рік тому +1

    @8:00 why do you need extra ’as string' there if arg1 === 'string' ?

  • @mark-at-driva
    @mark-at-driva Рік тому +1

    Great content and great shirt

  • @137dylan
    @137dylan 3 роки тому +1

    Hi Jack,
    2 incredibly important points I would like you to clarify, please:
    1. Did you record this series on the same day and purposely change your shirt for each video? If so, that makes them even better!
    2. It's obvious you're American, but I can't pinpoint your accent. I have a feeling you traveled around a lot when younger so never formed a specific US regional accent..
    Thanks!

    • @jherr
      @jherr  3 роки тому +1

      #1 Probably. If I have the content ready to go I like to do 2-3 and then edit and all that in one go.
      #2 I'm from Philly (Philadelphia) originally. There are a lot of Philly-isms in how I talk, or really slur, particular sounds. I'm working hard on trying to get rid of those, but old habits are hard to break.

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

    I just have one question.
    Why are you casting arg1 as string (line 16) since for this block to even run arg1 must be string, so if condition passed you would know for sure that arg1 would be a string? I don't see the point of casting it as one... Thanks.

  • @lookingforbino
    @lookingforbino 2 роки тому +1

    Hi Jack,
    I just searched, JavaScript doesn't support function overloading, so ....
    function parseCoordinate(str: string): Coordinate;
    function parseCoordinate(obj: Coordinate): Coordinate;
    function parseCoordinate(x: number, y: number): Coordinate;
    ------- divider----------
    from my understanding, the previous functions will be overwritten. How do you make them work?
    Thanks

    • @jherr
      @jherr  2 роки тому +1

      You are correct that JS doesn't support function overloading. The last function along the line needs to implement all of the previous API signatures. This feature is primarily around giving a function that has multiple argument signatures and easier to understand type signature in TypeScript.

    • @lookingforbino
      @lookingforbino 2 роки тому

      @@jherr Meaning, only "function parseCoordinate(arg1: unknown, arg2?: unknown): Coordinate { } " works here. The previous 3 functions stay there just for the demonstration, they don't work, right ?

    • @jherr
      @jherr  2 роки тому +2

      @@lookingforbino They don't work, but they aren't there for the demonstration. TypeScript will check to ensure that your call pattern of parseCoordinate matches one of the function overload patterns.

    • @lookingforbino
      @lookingforbino 2 роки тому

      @@jherr Thanks Jack

  • @sreekar_s
    @sreekar_s 3 роки тому +3

    Is it also okay to use unions eg. arg1: Coordinate | number

    • @jherr
      @jherr  3 роки тому +1

      Yep.

  • @bobvantpadje1490
    @bobvantpadje1490 3 роки тому +2

    Why would you personally prefer this over creating three separate functions? I feel like the readability and maintainability for code that uses function overloading is much higher than just creating three separate functions. Even if you want to have to parse functions close to each other you could just put them in an object, so you can call it like this: parseCoordinate.fromStrin(arg) or parseCoordinate.fromNumbers(arg1, arg2).
    For me this gives me a much better sense of what is going on inside my function. What would be your reasons to prefer function overloading over just creating multiple functions?

    • @bobvantpadje1490
      @bobvantpadje1490 3 роки тому +2

      Love your content btw :)

    • @jherr
      @jherr  3 роки тому +4

      I tend to look at the value of a function as proportional to it's reuse. A good function gets reused a lot. So I'm ok with trading a little implementation complexity for making a function that hints it's use really well, which is what function overloading allows for.
      Also, I usually go for lower numbers of exported functions if I can. So if I were making an XML parsing library I'd ideally like to have one function, parse, that would take a string, a stream handle, etc.and just do the "right thing" (tm). :) And function overloading would allow me to express all the variations of "parse" in that context.

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

    I think even this simple example can get very complex very quickly if I want to be really safe :D.
    1) Check if the object actually has the fields I need
    2) Check if x and y are indeed numbers
    3) Check if the string is provided in that very specific format, something like type CoordsStr = `x:${number},y:${number}`. But then I might consider a different format, for example different chars, optional space after comma etc. So I'd make a different overload functions and implement super complicated logic for checking the format (probably regex)
    Edit: No, just realized first two points are already ensured. So I'd do that maybe only to support Javascript use without getting some wierd values as a result. Like x being a function callback and y being all seven books of Harry potter

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

      Function overloading exists to solve the problem of interop with legacy JS APIs that had complex function parameter patterns, like $ in jQuery. I generally speaking wouldn't start a function native to TS using function overloading unless I had a really good reason to. Not just because it's probably a weird API signature, but also because I'm doing a lot of work at runtime on every call to figure out which signature I'm getting called with. Just IMHO.

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

      ​@@jherrI'm confused now :) In the video you say overloading is one of your fav features but here it reads like you don't use overloading unless you had a good reason to? Or I am just misunderstanding something...

  • @oOrbitZz
    @oOrbitZz 2 роки тому

    very cool stuff. I love this channel. I also tried below as the default to shorten the code. And remove the else part.
    let coord: Coordinate = {
    x: arg2 as number,
    y: arg2 as number,
    }

  • @lorenzodallamuta138
    @lorenzodallamuta138 2 роки тому +2

    Extending the idea that type checking doesn't extend to runtime, if you provide an input like "a:57,b:38" the overload for parsing strings will mistakenly return something along the lines of { x: 0, y: 0, a: 57, b: 38 } and typescript won't be able to warn you because it can't see into the result of parsing the string before it happens. So I'm not sure this is a good example, but maybe you point this out already in your interview questions... :P

    • @jherr
      @jherr  2 роки тому

      Fair enough, but it's not unusual, you might have to make that type of string parsing code for reading data from a file, and yeah, the implicit contract there is that your code will ensure the type-safety it advertises.

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

      This is definitely not type safe, using as all over the place like this :p worth to mention …

  • @josemfcheo
    @josemfcheo 3 роки тому +2

    This is art

  • @sagarreddy7461
    @sagarreddy7461 3 роки тому +1

    Great content jack

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

    What's the point of declaring the parseCoordinate function three times before the actual implementation? If I remove those declarations, the code runs anyway, since the final parseCoordinate function accounts for all three argument types.

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

      The code will run yes, but that's always the case with TypeScript. The function overloading is only helpful to TypeScript to provide more restrictive (and accurate) function signature combinations.

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

      @@jherr Got it, thanks! Also, 30 minute response time to a comment on a 1.5 year video - wow. You're doing an amazing job.

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

    awesome, superawesome! Amazing

  • @PS-dp8yg
    @PS-dp8yg 3 роки тому +2

    Awesome content! I'm not a typescript developer and never knew typescript supported function overloading and learned something new today. However, with that being said, I'm not a fan of this at all! The way typescript handles function overloading is just gross. Can you imagine the checks needed if wanting to support more scenarios?

    • @jherr
      @jherr  3 роки тому +3

      Undoubtedly a lot, but this is what some JS functions were doing anyway. This is just a way to put different type signatures on it, so that it's easier for someone to consume a function that is written this way.
      You don't have to use this mechanism and you don't have to write a single function that takes a variety of arguments. But if you do, this feature will help you express the API surface of that function far more succinctly.
      I understand where you are coming from. In other languages each implementation would have its own body. But Typescript is limited (by design) in that it the type annotations can be removed from the code and the code should still run. So since JS can't support function overloading the "usual way" it's not possible for Typescript to support that either.

    • @PS-dp8yg
      @PS-dp8yg 3 роки тому +1

      Thanks for the reply. I have a hard time why typescript cannot support each function to have its own implementation. I understand why in JS we can't because of the dynamic nature of the language and the ability to pass N number of arguments.

    • @jherr
      @jherr  3 роки тому +4

      @@PS-dp8yg Two reasons, first that Typescript isn't adding new language features to JS and is designed to be removable. And second that the code generated by TS has to be JS, and compatible with JS. So in order for that to work the compiler would have to merge your implementations into one function and then write the detection code to route you into the right version.

    • @PS-dp8yg
      @PS-dp8yg 3 роки тому +1

      @@jherr I see. Thanks and subbed.

  • @vzlomer1000
    @vzlomer1000 2 роки тому +1

    thanks, good video

  • @razorbelle
    @razorbelle 3 роки тому +1

    Is it possible to do function overloading for arrow functions in TypeScript?

    • @jherr
      @jherr  3 роки тому +1

      Not in the same way because you are defining a constant value and not a function. You can define a pretty complex function signature that takes multiple variants and returns multiple different types based on conditionals. But you wouldn't get the same quality of hinting that you do with the function approach. The overloaded function approach gives the consumer a list of the possible approved variations of function signatures.

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

    I find it very useful, but why would I want to overload functions like this? Wouldn't it be better to define dedicated functions for each kind of parameter? Such as "getCoordinatesFromString", "getCoordinatesFromNumbers", etc...?

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

      Javascript allows for making functions that take different types of arguments. Function overloading just makes that compatible with TypeScript. A classic example of this is the jQuery $ function. It would be a shame if we couldn't write jQuery code using TypeScript. TypeScript is designed to support all of the potential features of the JavaScript language, even those you don't choose to use.

  • @rachkulk3209
    @rachkulk3209 11 місяців тому

    Great tutorial. Thanks for the series. Why typeScript is not yelling for below code? [vals[0]] below can be anything other than x,y also.
    if (typeof arg1 === 'string') {
    arg1.split(',').map((val: string) => {
    const vals = val.split(':');
    coordinate = {
    ...coordinate,
    [vals[0]]: Number(vals[1]),
    };
    });
    return coordinate;

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

    Object keys are treated as strings? When you did key as 'x' | 'y' does that mean the keys are kept as strings?
    In a previous video, u made an object IDs which had key-value pairs like this: 10:'a'.
    In this, the key 10 is also kept as a string?

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

      Object keys can be strings, numbers or symbols.

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

      @@jherr but x is a symbol right? Why did you cast it as string then?

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

      @@anonymoussloth6687 Can I get a time reference so that I can help you out better.

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

      @@jherr 9:19 it's when you did key as 'x' | 'y'
      X and y are symbols right? Shouldn't it be something like key as x (without the quotes)?

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

      @@anonymoussloth6687 No, 'x' and 'y' in this case are "string literals" www.typescriptlang.org/docs/handbook/literal-types.html#string-literal-types . They are not JavaScript symbols.

  • @Calebwaldner
    @Calebwaldner 3 роки тому +1

    Great video

  • @xanderexpelimus5237
    @xanderexpelimus5237 2 роки тому

    type DescribableFunction = {
    description: string;
    (someArg: number): boolean;
    };
    function doSomething(fn: DescribableFunction) {
    console.log(fn.description + " returned " + fn(6));
    }
    how do we run this? i don't get it

    • @jherr
      @jherr  2 роки тому

      Like this:
      const descFunc = (x: number) => x > 5;
      descFunc.description = "describable function";
      doSomething(descFunc);

  • @brahim_boussadjra
    @brahim_boussadjra 3 роки тому +1

    I've tried out to overload a function and it doesn't work

    • @jherr
      @jherr  3 роки тому +1

      Jump on the Discord server and into the #typescript channel and tell us what your issue is and maybe we can help you out.

  • @thehaptiK
    @thehaptiK 2 роки тому +1

    Perfection;

  • @channabandara
    @channabandara 3 місяці тому +1

    valuable

  • @AntonShestakov
    @AntonShestakov 3 роки тому +1

    Thanks

  • @韦磊-o4b
    @韦磊-o4b 2 роки тому

    why not use specific type instead of unkown? like:
    function parseCoordinate(p1: Coordinate|string|number, p2?: number): Coordinate {// some code}

  • @alexandre158
    @alexandre158 3 роки тому +1

    Why not returning directly from inside the ifs conditions ?

    • @jherr
      @jherr  3 роки тому

      Personal style. You could return out of the if's if you wanted to.

  • @zykoz6826
    @zykoz6826 2 роки тому +1

  • @emdadgar_official
    @emdadgar_official 2 роки тому +1

    i hope see many more course about TS from you . everything is clear upuntill although you don't speak very clear English for non-eng x)

    • @thingshappen5607
      @thingshappen5607 2 роки тому

      This is funny :) This guy is American. Thanks for putting an effort into this series, Jack! 🤘

  • @cihadp
    @cihadp 2 роки тому

    Maybe it is better if last overloading function's string parameter is like type StringCoordinate = `x=${number},y=${number}` | `y=${number},x=${number}`

  • @KhanhNguyen-hd7ws
    @KhanhNguyen-hd7ws Місяць тому

    What if there’s 2 different objects types?

  • @avneet12284
    @avneet12284 3 роки тому +1

    Wow !

  • @rokinos
    @rokinos 2 роки тому

    parseInt(value, 10) = Number(value) = +value

    • @jherr
      @jherr  2 роки тому +1

      Truth. Old habits die hard.

    • @rokinos
      @rokinos 2 роки тому

      @@jherr I couldnt understand parseInt(value, 10), it wasn't clear as Number(value) or +value

  • @MaksymMinenko
    @MaksymMinenko 2 роки тому

    Instead of "ts-node" I use "tsc --watch" in one terminal, and "nodemon build/...js" in the other.

    • @jherr
      @jherr  2 роки тому

      Have you looked at tsx?

    • @ChillAutos
      @ChillAutos 2 роки тому

      What do you mean about tsx? I do exactly what the max said daily. What's the issue with it? Also love your content.

    • @jherr
      @jherr  2 роки тому

      @@ChillAutos Can you give me a time reference?

    • @ChillAutos
      @ChillAutos 2 роки тому

      @@jherr Sorry what I meant was I didnt understand your reply to the top comment in this thread "Have you looked at tsx?". What was the issue with that?

    • @jherr
      @jherr  2 роки тому

      @@ChillAutos Ahhh, gotcha. My bad too. Anyway, tsx is a new alternative to ts-node: www.npmjs.com/package/tsx Totally confusing name though for sure.

  • @dannyroberts4067
    @dannyroberts4067 2 роки тому

    I like these videos but there is a tendency to explain the obvious stuff but gloss over the complicated stuff

  • @Dylan_thebrand_slayer_Mulveiny
    @Dylan_thebrand_slayer_Mulveiny 3 роки тому

    Anyone who thinks this generates better code is delusional.

    • @squdge
      @squdge 2 роки тому +1

      Never have I felt a more secure react application than when I switch to Typescript. So I guess, that's just like your opinion dude.

  • @Smithy-so9be
    @Smithy-so9be 3 роки тому +2

    Another great video. You can also combine this with user defined type guards to cut down on casting values: basarat.gitbook.io/typescript/type-system/typeguard#user-defined-type-guards