TypeScript and Vue 3

TypeScript and Vue 3 Declaring Prop Types

Learning Paths:
Check out a free preview of the full TypeScript and Vue 3 course:
The "Declaring Prop Types" Lesson is part of the full, TypeScript and Vue 3 course featured in this preview video. Here's what you'd learn in this lesson:

Ben discusses which APIs will be used during this course, TheNavBar component, and demonstrates declaring more descriptive prop types.

Get Unlimited Access Now

Transcript from the "Declaring Prop Types" Lesson

>> Let's dive into our app. One of the questions that might be coming up is you might be thinking, well, okay, in View 3, there are two ways of authoring components. There's the options API and the composition API, which we'll be using today. I will be showing you both because both are still valid ways of writing components in View.

[00:00:16] But we will definitely be spending more time in composition API for I'll explain later why, but this way people get a flavor of like how it feels to be in both. And that way, you don't feel like you have to do one or the other when it comes to building your own project.

[00:00:30] So let's start with a scenario that we're all pretty familiar with when it comes to view. Let's go ahead and take a look at the nav bar component. Okay, so this nav bar component, let's contextualize what's going on here. So let me go ahead and open up here.

[00:00:44] The nav bar is this piece up top. And so typically, in a nav bar, we might have like say a tagline as a product that we'd pass down. So if you look at app.view here, we have the navbar, and we wanna define what it might be, right? So typically, I might be like, okay, well, my tagline here is track everything you want to eat.

[00:01:08] This is great. And so if we switch back over to the site, you'll see it appears up here in the upper left, everything seems pretty good. But for anyone who's worked with code for a while, you'll notice that one of the problems here with the way we've defined the props is that it doesn't tell you very much besides what it's called.

[00:01:26] And so what we wanna do even prior to TypeScript is we'd want actually define more information about the props. So the way we would do this typically, in standard view, is you say, okay, we'll make prompts an object instead of an array. And then the tagline here we can actually define what type it is, so we might be like it's a string, for example, this is what we expect.

[00:01:44] And so typically, you'll even dive a little bit further by actually having it say, okay, type string, and then you can have it to have either default property or the required property. So, in this case, we'll go ahead and just do that real quick. So this is feeling a lot better, right?

[00:01:59] This is what most of us are familiar with. And if we wanted to do more, and so this was nice because what we would get to do is we'd say, okay, now we can do things like, okay, in our data property, we can say, okay, we have a tagline.

[00:02:13] And this is, let's just say test string for now. And we can now make this a reactive property and this is great. And so we can see here everything still works. But the problem was what happened when someone passed the wrong thing? And so this is where it was nice because in the case someone passed like 123, for example, and this is a number, what we find is that inside of our app, when we actually open it up, you'll see that there's an invalid prop type check, which is nice, because something is yelling at us.

[00:02:42] On the other hand, if you don't have your console open, and you're not paying attention for this, if you look back in our code, there's really nothing to indicate that anything else is wrong. And so this is a limitation on prop type checking. But if we really think about it, though, this is actually the kind of mental model that TypeScript is really built around anyways.

[00:02:59] Which is around documenting what you intend to do, and then helping you to just sort of prevent yourself from making mistakes in that regard. So in this case, in the event, we really want it to be TypeScript to a string or a number, we could just say, okay, well, it's a string or a number.

[00:03:13] This was a default in text that's built right out of the box for view, which was really nice. And so, here's another limitation that you probably have run into when it comes to the prop type checking that we have with you. So let's go and take a look at restaurant card, for example.

[00:03:30] I don't know about you, how many people have done this before where you have a object that you're passing down to a component, and the type is just object. Now that's nice from at least knowing what the primitive is, but then otherwise you have no idea what's inside of that shape.

[00:03:44] And then oftentimes you find yourself switching between files, you might miss some things, it'd be nice if this was a little bit better. So first thing first here, we have this restaurant and let's see, again, how will we typically debug this? We'll say, okay, well, the restaurant is being, where's that being passed?

[00:03:58] Well, let's take a look. So if I go inside of here, and I look for restaurant card, restaurant card, okay, it's being imported on restaurant page. All right, restaurant page here is, let's see, let's scroll all the way down. And you're like, okay, here's where it's being called, and it's being passed by the item, the item is passed by filter lists.

[00:04:18] So if I then go ahead and hold Option click on this, it'll jump me up to where filter restaurant list is and then is here are the restaurants, then I can jump up. And, okay, here's the shape of my data, right? This is kind of how the process is, this is actually pretty normal for us to debug.

[00:04:33] But this is a lot of work, especially when code bases can get infinitely more complex now. Because some of you might have been like, well, I would have guessed it was that, but we all know, right, code does not always organize as well. So that's usually how you might debug it.

[00:04:46] So we might be like, okay, okay, so we know this is the thing, so let's copy it over. Let's go into restaurantCard, and let's at least documented somewhere, right? So we might be like, let's let's create a comment block and just be like, okay, Restaurant, so what do we got?

[00:04:58] We got id, so the id is typically a string, and then we have, in fact, these are all strings. So at the bare minimum, let's document the shapes. Let me just multi cursor select. So for those who haven't done this before, I'm just holding down Command while clicking, I think it might be Ctrl on Windows.

[00:05:18] And so this is the general shape that we have for our restaurant. And so once we have this, normally you would throw this in like a JS doc block, and then you would hopefully VS code would pick some of that up. And that would be nice. But we're here to learn about TypeScript and how that looks, right?

[00:05:35] So now that we have the shade, let me just go ahead and actually comment this, so it doesn't report any errors. And let's go ahead and actually make sure that we tell you that we wanna use TypeScript for this specific component. And so the way we do this is we come up here inside the script block, and we declare its language.

[00:05:50] And the language equals TS, which stands for TypeScript. That's it. Once you've done that, you basically use the TypeScript compiler. And then the next thing we need to do though, is that we need to actually tell TypeScript what kind of object we're about to pass into it. Because what you'll notice here is that inside of View, one of the things that sets it apart from other frameworks is that it does this export default object thing.

[00:06:12] And that has sometimes mixed results especially when it comes to types, so what we have is this helper function called defineComponent from View. So when you import this, it basically tells TypeScript what to expect and kind of roughly what to guess when it's making a bunch of assumptions about your component.

[00:06:30] And so then instead of just exporting a default generic object, now we're gonna say, we're gonna wrap it in define components, oops. And then, we wrap that on the bottom. And then, That's it. So far so good. Of course, now the question is, okay, how do we tell it that we want it to actually become this restaurant type?

[00:06:57] And so, for now, what we're gonna do is we're gonna learn about how to declare types. And so we actually can do it directly inside this component, we're not gonna get crazy here. We're gonna create a custom type called restaurant. And so this keyword here, if you've never used TypeScript before, is specific to TypeScript basically, is a const let, what are you declaring?

[00:07:14] Declaring a type, we're declaring a type of restaurant and the shape of this object is gonna be this thing that I just created. I'm gonna cut and paste this over here and show it like this. And so what you'll notice here is that there's a couple of syntactical things that might look a little bit odd, like there's no commas, or anything, but this is just how it is defined.

[00:07:37] And for those who have a little bit of TypeScript knowledge, you might be wondering, well, what about interfaces and yada, yada? For the purposes of keeping things approachable and simple, we're sticking with types for now. It's one of the things where as you need interfacing and that kind of stuff, we'll reach out for it, but for now, we're just gonna keep it simple with types, okay?

[00:07:54] Now that we have this, you're probably thinking, okay, I know what I'm gonna do, I'm gonna come in here, and I'm gonna say a restaurant and everything's gonna be fixed. Except wait a second, what's going on here? It says that it's only referring to a type, but it's being used as a value here.

[00:08:14] And so this is where it's a little bit weird, right, because this is not what you would typically expect it. But what we have here, and this is where you're gonna need to learn a new thing when you're using Options API, is that one of the things we have to do when using type with it is using this as keyword.

[00:08:31] And this is known as typecasting, where we're basically telling TypeScript explicitly what is going to be. And because we're using options API, again this is some of the hacks around that makes it a little bit trickier compared to composition API is that we need something called a prop type.

[00:08:48] So what I'm gonna do is import a type called PropType from vue. And so this is one of those things that we need, once again to help type of understand the convention that Option API provides for developers. And so what we do is we say well we need the object to be a prop type, and then we have this new convention in TypeScript which is the brackets greater than less than symbol.

[00:09:15] And if you think of them like parentheses, like you're passing in an argument, think of it like that. Like you're saying, I have a prop tight that's going to be a type restaurant, but because this is TypeScript, it wants to be explicit, then it is important that, not even important it has to be the greater and less than symbols.

[00:09:32] And just like that now you'll see that if we hover over a restaurant, it'll actually let you know as a prop type restaurant. And now going forward, you can actually learn more about the thing that you're working with before sort of like having to jump around different files, and this is super nice.