Check out a free preview of the full TypeScript Fundamentals course:
The "Functions: Types" Lesson is part of the full, TypeScript Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Mike discusses how functions are types and how interfaces can be used to describe a function type.

Get Unlimited Access Now

Transcript from the "Functions: Types" Lesson

[00:00:00]
>> Mike North: So back into the world of TypeScript. So we talked about object literals, rest and spread properties, getters and setters. We're gonna shift gears now, move away from objects and into functions. So functions have types, just like any other value in JavaScript. They have a first class value type in JavaScript, or a first class value type in JavaScript, and a first class value type in TypeScript.

[00:00:27] So on top we have a function type. And you can see like any other value, we've got the name of a variable, a colon, and then something. And that something describes the type. And what we have here is the arrow function notation here, and I advise that you always use this, right?

[00:00:46] There are other things you may see out there but I advise that like this is the more conventional thing to do for TypeScript that is written from here on out. And what we have here are arguments having particular names, and particular types. And a return type, and that's what that fat arrow is used for.

[00:01:03] It almost looks like an arrow function, except what we're returning is not an expression, it's a type. Below, we have the value of that function. So this up top, you can call this a variable declaration. And on the bottom, you can call this a variable assignment. They kind of look the same.

[00:01:21] Note that if we already know that like this function has a particular type, we are freed from having to do any type annotations on that second line. Because we already know it's the same thing as like when we say, if we were to say we've got a card and we define that this is a card and then we pass something in, it's gonna figure out what's going on there.

[00:01:49] Or a better example would be if we say we have a empty array of numbers and we've defined that this variable is of type numbers square bracket. On the right hand side, we can just have an empty array literal and we're fine. That's a numbered array. Typically, you only need types on one side of the assignment operator.

[00:02:09]
>> Mike North: So, that's pretty cool. And again, you can use this anywhere else that you would use type annotations. Meaning if you had an array of functions. That may seem strange. But that's how listeners work, right? Add a mouse listener, so we create an array of functions. And then we loop over that array and then evoke each one of those functions.

[00:02:34] And you could define that like probably wrapping that whole function type in parentheses. And adding square brackets to the end of it and there you go. You've got an array of functions and each one of those functions should take arguments of certain types and have a return type that matches that, which is fantastic.

[00:02:56]
>> Mike North: So, we can use interfaces to define function types as well. This is starting to get a little abstract. So you would call this an interface that describes the call signature, right, the call signature like a function call. So on the left side instead of the name of a property, we have parentheses.

[00:03:20] Think of those as like the parentheses that indicate you're invoking a function as opposed to getting a value of off something. Does that make sense to everyone? And so what we're saying here for this interface, we expect to receive as an argument a mouse event. And the return type is void.

[00:03:45] So if we have a click listener here, we can use that click listener, we can basically say, you're gonna receive an event, and then you can console log. We don't have to return anything. And in fact, we can add this event listener in the following way. So the way this works, and that works.

[00:04:05]
>> Mike North: So the way this works, it ensures that these functions are bound to the appropriate context. So hopefully you should at least at some level where you kind of know it when you see it. You should have an understanding for how this works in JavaScript, right? It is the calling context of the function.

[00:04:29] In this case you might have a click listener that really depends on being called in a particular context. And what we're saying here is that, click listeners, when you refer to this, it can only be referring to a window type. So this would be a situation where, when you invoke these functions, you are going to invoke it in a very specific context.

[00:04:55] And that prevents anyone who is implementing one of these things. Right, if you implemented a different click listener in this second part here, and you were saying like, this.x = 57 like you expected some other thing there, you can't just go and treat it like any old thing.

[00:05:13] You must treat it as a window object, right. So if for example you were to try to invoke it directly like this, right? Where undefined is the calling context in strict mode, undefined is the calling context. Basically it's saying the calling context is void, you can't just invoke a mouseListener like this.

[00:05:40] You'd have to do myListener.apply window comma bracket new MouseEvent. Does that make sense? So this gives us type safety even on the calling context, which is fantastic