Visual Studio Code

Annotating Types

Visual Studio Code

Check out a free preview of the full Visual Studio Code course

The "Annotating Types" Lesson is part of the full, Visual Studio Code course featured in this preview video. Here's what you'd learn in this lesson:

After showing how to add types with comments, Mikes takes questions from students.


Transcript from the "Annotating Types" Lesson

>> Mike North: So let's talk about ways, without going full TypeScript. Let's talk about ways that we can annotate types, add information to our JavaScript in the form of comments. So the main way to do it is to use this @ type kind of comment here. It is a JSDoc comment.

JSDoc is just a particular convention for writing comments in JavaScript files. And you gotta make sure you begin with the two asterisks here, it always has to be an in-line comment. Basically, it always has to look just like this where between the braces, you have the type that you wish to, basically, here we're saying, value is of type number.

So, in this case, you would start to see this is an error, here. We can paste that in, see what happens. I need to turn type checking on.
>> Mike North: And so, even if we were to get rid of this, now, you can see, before we had the initial assignment of this variable.

That was determining the type. Here we're annotating it. So if I were to change this to string and save it.
>> Mike North: It just hasn't picked up on something. Come on now.
>> Mike North: There we go. Just had to kick it in the butt. It was a background process, we were probably waiting for it to come back.

>> Mike North: So if you change it back to number, let's see how long it takes.
>> Mike North: It does take a little while.
>> Mike North: All right there we go. Apparently you have to perturb the code a little bit to get it to actually do it's checking. But we're getting this and in fact we can, if we look at this problems tab, which is in this panel at the bottom of the editor.

You see that it's been detected as it relate to this JS service here, right? And it says type 21 is not assignable two type number. So you can add this to a couple different files and then go and play whack-a-mole and swat, all of the type mismatches you may have.

>> Mike North: So constructors are regarded as type two. Anything that you can use a new operator with, you can use that as a type. So you can say that we have a type of React component or we have a type of cart store, or we have a type of listener support.

That would all be fine. It's still structural, you're just naming the structure. You're referring to a structure by name. But it is the structure that ultimately is looked at when we're trying to see if it, I have designed to receive this type, you've given me this thing. How do I determine what it's called type equivalence?

It is the structure that is the factor there, not the name.
>> Mike North: So we have built in type definitions for things like the DOM API, so querySelector. If we ran this, we would see this code will be happy, right? querySelector returns a variety of elements. It can return things like divs and image tags and meta tags and input elements and a bunch of stuff.

Now because it returns a bunch of different things, we could say, it provides us with something a little bit less specific than what we're looking for. But in this case, just as in this example, where we're invoking this function getFruit, we kinda know based on what we're asking for.

Based on the arguments that we pass in, we can say, look, I expect to get an orange. I asked for an orange, you gave me something back. I know it's an orange, right? So in this case, what we wanna do is, first of all, getFruit can only return the, think of it like the lowest common denominator, right?

It is the base class that all of the different things that returns have in common. So in this case it might just be a fruit, it returns a fruit. So what I'm trying to lead up to here is that in this example we had where we were grabbing the passwords field, we probably know that this is an input.

We only get an element out. How would we make this happy? How would we essentially say, I know what I'm doing? This is an input, I asked for an input. You could even put an input right here. Right to the left of the period. So that, based on the conventions we know about how querySelector works, it's gonna only return results that are of that type, it's guaranteed.

So what we would do there is you'd run into a problem if you just try to say let's define this variable as the correct type here, HTMLInputElement. This is what the error looks like. It's saying element is not assignable to HTMLInputElement. Basically, because this structure has things in it.

>> Mike North: This structure here has things in it that this structure does not. And here's your indication of the first thing that it's finding. Accept is missing in type Element.
>> Mike North: So the TypeScript compiler has found that element is lacking the accept property. If we look at that in MDN, you'll see that this is global input attributes.

It's pretty early in the list. Maybe this is is even an indication that the values are checked alphabetically or something. Or probably just in the order that they're expressed in the type definition. But it's basically saying look I tried to do the structural match, I found one thing that's missing.

So we can say right now these types are not equivalent, full stop. You're done.
>> Speaker 2: I missed something about a couple minutes in the chapter. I'm not sure if you covered it.
>> Mike North: So, the question online was, in Visual Studio code, where do you put the TypeScript file for a library you could use if it has one?

So, this is a question about, let's say I'm using React, and I want to add type definitions. It's a mega library, called definitely typed. And here's how you would install something like that.
>> Mike North: Or I'll use zero yarn, yarn add as a development dependency, types react. So @types that's pointing to this one thing.

>> Mike North: Definitely typed.
>> Mike North: One big mega repository, and if we look in this types folder, get ready for GitHub to choke.
>> Mike North: It's taking awhile. So, they had to show you the first 1,000 files, they omitted about 2,500, but here are type definitions for everything. D3, that should be interesting.

So here is the modular version of d3, the most recent version. And if we look at d3-scale, we can see that in here, it's got an index.d.ts, which is sort of like the index.js for type definition. And here we've got different scales just as typed definitions that are exported.

Now, even if you're just using a JavsScript project, and you haven't fully adopted TypeScript as the language you're going to use for writing you're code. You can still add these to your project. It's pretty much harmless. They're left alone by anything that doesn't care about types like people are using other editors.

But adding these to your project well make it so that you have the type definitions in place for some of the stuff that we're about to work with as it pertains to commenting and annotating types using JSDoc. So the information's available to you, the autocompletes full work as you would expect.

And for anyone who doesn't care about types, it's sort of left alone.
>> Mike North: So and you'll note that, for clever people who've poked through this a little bit, in my client folder I've also got this global.d.ts file where I've got some of my own types that pertain just to this app.

I can put stuff here and know they're globally defined things. Now again, if you're just ignoring any files that aren't JavaScript, if you're just using Babel, it'll skip right over this, it doesn't care.
>> Mike North: So,
>> Mike North: So, what we wanna do is basically perform what is called an explicit type conversion, or this is known in other languages as type casting.

And type casting is what's happening where we have the second comment, and then immediately following the close of the comment, we open a parentheses. And whatever expression is between these parentheses effectively, we're gonna regard that as the new type. So this will basically say whatever I'm given, I am saying as the developer, you will regard this as an HTML input element.

Regardless of what this returns, we are forcing it.
>> Mike North: And because, as we already saw, when we initialize variables, and the values have a type, we can infer that that variable is gonnahave that type as well. So, this first line up here, it doesn't really add anything anymore.

So, effectively, we've just sort of in a situation where we're annotating the type of something and the function, that we're using to initialize it, returns something that's a little too vague. We can just sort of move the comment to the right hand side of the assignment operator and we get what we expect.

And now this is regarded as an input element, and we could get its value for example which you can not do with a div.

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