TypeScript 5+ Fundamentals, v4

Functions & Return Types

TypeScript 5+ Fundamentals, v4

Check out a free preview of the full TypeScript 5+ Fundamentals, v4 course

The "Functions & Return Types" Lesson is part of the full, TypeScript 5+ Fundamentals, v4 course featured in this preview video. Here's what you'd learn in this lesson:

Mike explains how to add types to a TypeScript file and demonstrates adding type annotations to a function that takes two arguments and returns a number. The benefits of using TypeScript, such as catching type errors and improving code reliability, and the use of ESLint with TypeScript are also discussed in this segment.


Transcript from the "Functions & Return Types" Lesson

>> So we can return to our example we showed in the introductory chapter, where we had this add function that takes two arguments in. Now, we are in the context of a TypeScript file. And TypeScript is not super happy that we have these things and that they're not typed.

So we're going to give those types here. You can do the same technique here. So we're adding colon number and colon number, and GitHub code pilot is trying to help me out here, and add another number. So this represents the return value here. It's a lot more syntax, but you'll get used to it, meaning, you're gonna see colons all over the place and it gets a little odd.

If you're used to seeing parentheses and then the open brace right after it, like it's a little noisy. But now we can see a is a number, b is a number, and we return to number. And if we just change this, This will type, check. So here, let's see what the type error is here.

So previously, before we had this return type here, we can go back. You see that we were able to get this result, which is an any, and we were able to pass this in. Maybe some of you didn't even notice, I didn't notice, it just now. We pass this in as the argument to a promise constructor.

What should we be passing to a promise constructor? In general, what type of value?
>> Callback function?
>> It's a callback, it's a function. But because this is an any, TypeScript isn't warning us that there's problem here, right? You have to spot this. This is part of the benefit of using TypeScript, right?

So if we go back and we add these back in, now this is starting to come to our attention. So hopefully some of you in the chat and some of you at home who are wondering, what's the value of adding TypeScript to your code? It helps you catch these kinds of things more reliably.

And even once you adopt the TypeScript, if you have any's, these sort of wildcard types floating around in your code base, you'll start out that way. Particularly, if you have a JavaScript code base and you convert to TypeScript, you'll incrementally get to stronger and stronger types. But these effectively like untyped values floating around, they can silently be there waiting, it's like a bug that's waiting to happen.

And this is part of what TypeScript helps you catch more easily. Normally, like if this were a JavaScript code base, I mean maybe we have a linter that's smart enough to catch this. But if not, you have to wait for a user to go through this code path and you better hope you have test coverage here, where you would see like, okay, the promise constructor blows up because it has no callback pass to it.

>> Do you still need ESLint with TypeScript?
>> Very good question. ESLint and TypeScript work really well together. TypeScript is all about type checking, right? It's doing its work whenever an argument is passed to a function like this. Remember, we had red squiggles here when it was this string 4.

So TypeScript is great at catching this. It's great at catching assignment errors or things like this up here. It doesn't really try to do much for you in terms of code style, and sort of best practices. So I look at them almost as like a low level and a high level concept.

And in fact ESLint rules that are written to use type information can be incredibly useful. So there is a project called TypeScript dash ESLint, which I think the TypeScript core team contribute to do significantly and it's sort of like more information for lint rules to use. And you can start to get really crisp about the kinds of problems that you detect.

So don't throw away your linter. It's even more valuable with TypeScript. Rod asks a good question. Doesn't TypeScript infer the return type of the function to number? It will, It will. The fact that we're returning a plus b, it knows that that's a number, it'll return a number.

There are pros and cons here. It's more concise, if you updated the function, it would update the return value. I tend to want to type my function returns because it represents sort of an encapsulation boundary, and it's a contract that I have to live up to. So for example, if we have this and I do this.

Okay, so I just added this. Now, if I didn't have this return type, and let's say I was using this function properly. Everything seems fine, right? Let's ignore this promise one. Seems good, seems good. But is this good? What's happening here? Look at that. What this means is, it could be a number and it could be undefined.

So this is a little sneaky bug waiting to happen here. So yes, we were able to alter this function and we could just alternate and TypeScript automatically updates this function, the return type, and it says it could be undefined. But I would prefer to be very explicit about what I intend to return from the function, and then I can live up to it.

So, let's say, just for a moment, I'm gonna write one more line of code here All right, toExponential. So that is a function, that's a method available on number. That's all we need to know. All right, let's add this line back in. So I'm gonna get an error, but I'm getting it kind of late.

This is almost like where you'd expect a duck-typing error to pop up, where you're getting right up to the point where you're reaching for this method and you're trying to use it, and then TypeScript goes, oops, this thing could be undefined. Cuz there's the possibility that we didn't, our coin flip didn't work out in our favor.

I don't like this for one big reason, and it's really about where the error shows up. Let's imagine this file here, it was in a different JavaScript module, a different TypeScript module. I'm gonna see errors at all the call sites or all the attempts to use return values of my function.

When I really wanna see errors here, I wanna see an error here that's saying, look, you stated you are gonna return a number from this function and not all paths in this function end up with you returning a number. And so I think this explicit return type here ends up bringing errors closer to the place where you probably want to make the fix.

You'll see me not put explicit return types everywhere in this course when I'm writing code intended to go to production, I tend to wanna do this, right? It's a little mini contract that this function has with the outside world.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now