Vue.js With TypeScript A Beginners Guide

Savoir Faire
12 followers
8 Video Views·Oct 27, 2022
Hey developers! Today we are going to look at TypeScript support inside Vue.js. So we're going
to take a look at a couple of different ways we can do that. We're going to look at the
official documentation and then I'm going to walk you through a few examples of how to get it
started. And then we're going to look at how you actually implement it inside your Vue.js apps.
So make sure you stay all the way to the end and learn all about it. Hey and if you don't know,
my name is Eric. I'm a big fan of Vue.js and this channel is all about web development,
programming, frameworks. If you guys like that type of stuff, make sure you click on that
subscribe button and click that like button for the algorithm. I would really appreciate that.
So before we get too far into this video, I want to say thank you guys. If you didn't
check out my last video, I released a video on the top 150 YouTube channels. So in fact,
right now, as of this recording, the repo that I created just in a couple days has over 437
stars. It's been forked like almost 60, almost 64 times, 64 times. And just tons of people have
been throwing pull requests up. I've probably merged like 30 of them so far. And I've had,
you know, probably another 50 channels, maybe even more, maybe, maybe closer. Yeah,
probably 50 to 60 channels. And you can see here now we have non-English channels.
So if you don't know, this is a GitHub repository that lists YouTube channels. I just want to have
one place online where people can post their YouTube channels. If people are looking for
different types of YouTube channels for developers, they can come here and find it. So now we have
English channels on tutorials, informational, live coding. We have non-English, we have Russian,
Hindi, Turkish, Italian. So we just have tons of information on here. If you haven't checked out,
I'll put a link in the description below, but yeah, thank you for everyone that's contributed.
And hopefully we can still grow this to have every single development channel on YouTube.
That'd be awesome. Okay, enough of that. So let's go into our app here.
And so I have Visual Studio Code open. And if you look at the official TypeScript support
documentation, it tells you a little bit that it's obviously fully supported, you know,
we don't have to worry about it. And that there's some NPM packages, it has all the types added,
and even tells you some recommended configurations. But we're not gonna worry about the
recommended configurations, because we're gonna use Vue CLI and start off that way.
If you're taking an existing Vue project, and you want to add TypeScript to it, that's a little bit
of a different process, maybe in a separate video, I'll show you how to do that. But let's just
assume that you're creating a brand new project using the latest version of Vue CLI. And by the
way, it's probably best that you use an IDE that has TypeScript support like Visual Studio Code.
I mean, I think that's probably the one of the best ones. And then also there's a Vtor extension
that you can get if you don't already have it inside Visual Studio Code, which gives you some
nice tools to, nice snippets to easily create a TypeScript file. And also there's some for
Webform as well, WebStorm. So I have the latest version of Vue CLI, which I believe as of this
YouTube video is 4.1.2. So if I do Vue create, I don't know, YouTube TS, it's going to ask me some
questions here. So first, I have some preset ones, we don't worry about that. But I'm gonna manually
select features. And obviously, I want to choose the TypeScript one. So that is the most important
one. And then, so now we have this choice if we want to use the class style component syntax,
or the non-class style component syntax. Now, if you want to use full on ES6 classes inside your
Vue app, then you want to type yes here. If you don't want to use ES6 style classes,
then you want to type no here. And then you're going to use a slightly modified
default export of Vue. You actually use something called Vue.extend instead of
the default export that you usually see in our single file components inside Vue.js.
But I'll show you both ways. We're not going to get too deep into each, but I just want to show
you what's possible for both. So let's say yes here for the single class style components.
And then I always type yes here, it asks you if you want to use Babel alongside TypeScript,
which I don't think there's any reason why you not want to. So I always type yes here.
That'll make sure if you're using the latest TypeScript features that it obviously transpiles
down to the correct JavaScript. And then keep in mind, if you look actually at TS Lint's
documentation, the creators of TS Lint have decided to deprecate that, and they're rolling
all the linting into ES Lint. So if you're using TypeScript, the correct way to do it is use the
latest version of ES Lint and not use TS Lint. So as it says right there, it is being deprecated.
Now I'm not sure how far along in the ES Lint they're getting with the TypeScript
support in there. I think it's pretty good right now. If I stand, send me if I'm correct,
put a comment below if you know any difference. So we're just not gonna worry about that. We're
gonna do it with error prevention only. And then we're going to do lint on save and dedicated config
files. And I'm not going to save it. And so this will just take a moment and it'll create our
brand new project and we'll jump in and look at it. Okay, great. So when heading installed,
we can just make sure it works. We'll just change directory to our YouTube TS and npm run serve
and npm run serve. Type that right. And let's go ahead and start it on local port 8080, I believe.
While it's doing that, let's take a look at the structure of it. Actually, it's done. Let's
go ahead and open it up. You can see here, this is a Vue.js plus TypeScript app. Pretty simple.
This normal welcome page that we always see. Now let's take a look at what it looks like. So
first, if we look in the package.json, we can see kind of look under the hood and see what this
gave us to start off with. So we look here, obviously we have Vue. Now there's a couple
different ones. We have this Vue class component library, which gives us es26 TypeScript class
decorator for Vue components, and this Vue property decorator. So those are the two and
obviously eslint that we chose earlier and TypeScript and Vue template compiler. So this,
this is everything we need to start, but these two are the most interesting here. So let's take
a look at those first. If we go into our GitHub and take a look at what these are. So the Vue
class component is the TypeScript decorator for class Vue component. And what this does is you
essentially create your classes as if you're using this kind of class standard here. So you
have this at component, which is this decorator called component, which we'll talk about in a
moment. And then you have this export default class app extends Vue. And what this does is now
you have essentially like a class. So if you're coming from something like, oh, I don't know,
Angular, this kind of feels a little bit familiar. So let's take a look at it, what it did for us.
So if we go into our components or hello world that we normally have everywhere,
this is what it looks like. So let's just delete a few things in here. I always hate this,
all this stuff. We'll just delete it all. We'll save it. And now you can see here, we have the
props. So now we have this at component and they have this Vue property decorator. So that's the
other thing. So if you look here, here's the Vue property decorator library, and this gives us
things like app prop, app prop sync, model, watch, provide, inject. So it gives these other
decorators that we can annotate our classes with. So it has that prop here, the private message,
and doesn't have an export class in here, but we can, oh, here it is right here, export default
class, hello world extends Vue. So this is essentially the app right here. So let's save,
let's save it right now. And if we look at it, okay, we just have the logo at the top,
and we deleted everything else in the message. But let's say we wanted to add another data
property. So instead of having to do something like creating a data object, and then returning
back an object, we don't do anything like that. Now, since we're using this class syntax, all we
need to do is add a property inside this class here. So we'll just say, I don't know, Eric,
and we have equal, and this will be hello world. So now we have Eric here, I can just add
a second thing in here, Eric, save it. Now I have hello world. So this is essentially the same
as something in our data object. Since now we just can use a property inside the class. Now
you're probably thinking, what about computed properties? Well, the computed properties,
we look back at our documentation, you can just do something like this, get. So we have getters.
So this is if you're familiar with getters and setters, you can do a getter. I know. Let's see,
full name. Let's do this. Let's have, let's add one called first name. And we'll have one called
last name. And we'll have some called full name. And that'll return. And we look at here,
the syntax has to be a method. And we'll return this dot first name, plus this dot last name,
we'll come back up here. So we'll put first name. And we'll put last name. And we'll put
full name and see if that works. So we do that. Cool. So hello, world. Hello, world. Hello,
word. Hello, world. But let me change the name to Eric Hanchett and refresh it. I gotta save it.
There we go. Reloads. Cool. So now first names, Eric, last name, and then Eric Hanchett is the
full name together. Now, obviously, if I want to do this correctly, I probably want to add like
space or template, template, literals, whatever you want. So now this is how we do computed
properties inside of here. So what about a method? So methods are just methods. So we can
do something like this. Eric, I don't know, we can add a new one, like a counter equals zero.
And then if we want to do counter here, we just have a counter. And we'll just do this dot
counter. Well, we probably don't want to do increment counter, we don't have the same name
as the property. Plus plus. And then we can have an h5 here. And we'll have counter. And let's say
we wanted to increment that counter. So we'll have a button says press me. And we can still use the
same syntax we use for our templates with the events here, like on a click event, we'll do the
increment counter, save it all, have a button. And so that gave us an error. Let's see what we
did wrong here. We look at console. Oops, it's saying here, the increment counter, I have a typo.
So increment, let's try that. Cool. So now the counter is incrementing. So yeah, I mean, that
looks all correct to me. So yeah, so that's how you can add methods. Now you're probably thinking,
well, you just added TypeScript, but you're not using types at all. Well, we can certainly start
using types. So I could have, I can do a property here called, you know, add, let's say, zip. And
we get to put a type string. And now Visual Studio code should notice that if we try to sign a number
to the zip file, it'll give us an error in the end here. So if I put increment counter here,
and I put this.zip equals, I don't know, one, you can see there's a red line underneath it.
If I put my mouse over, it says type one is not assignable type string. So of course, since we
have zip here, it's type string, it's not going to work correctly. We could also, if we were
returning things, we can add return values to this, like this, maybe this is supposed to return a string
or a number. And now it's giving an error that a function whose declared type is neither void nor
any must return a value. And it's not returning a value here. So obviously, that's a problem.
Obviously, technically, this is just a method. So I don't really care too much about this. But
this first name is returning string. So I could put in here string. And everything works correctly.
But once again, if I put something like number here, it doesn't work, gives me an error,
still compiles correctly, but gives me error in the, in the vtor here. Now you could change
your ESLint setting, the ESLint settings, and do some different rules that if you have errors in
your TypeScript that it won't even compile correctly. There's a way of setting that you
can also look at your tsconfig and see how it's set up. I'm not going to get into that today,
because that's a little bit more advanced. But there's certainly ways you can do that,
too. Nixie even has shims for TypeScript. So it can get a little bit more complicated.
So I'll put this back to a string. It can get a little more complicated if you want to do
some other things. So we have this props here. So we can declare everything that's being passed
into the hello world component using this app prop. But if you want to do watchers, or models,
prop sync, then you just all use all these different decorators. If you want to do lifecycle
hooks, you just type in the name of the lifecycle hook. So like, you know, mounted, you can do like
console log mounted, mounted with an M, save it. And I'll leave a link to these descriptions,
too, so you can follow along. And now you can see there's mounted in the console. So that this is
essentially how you do it. Now, I think the best way if using modern day TypeScript, and I think
I could probably do a whole course on this, is what you want to do is add types to everything
in your app. And that's really the power of TypeScript. Obviously, as the name applies,
if you put types for everything, then you can more easily and quickly find errors. So anytime I
would talk to a back end, or anytime I have complicated data inside objects, I would make
an interface for it. So I could definitely see, like the proper way of doing a TypeScript app and
view is I would probably create a couple of extra folders here, maybe an interface folder to put all
my interfaces, I would probably add some classes too. So if I want to have a really tight data
model that I want to add stuff to and add it into a class, I can do that. So that would make sense,
maybe I had like an alert class. And you can have all the nice things about TypeScript,
then you can extend it, you can use interfaces, you can create abstract classes, you can do all
that with the TypeScript ecosystem. So but I think the basic part of it would be to start off and
start adding types to everything. And that's where you're going to catch the errors while you're just
typing in and creating and that would be anytime like it's going to infer this is a type string
because I just equal type string. But you know, when I work with TypeScript, I'll have maybe 20
different properties on the top of my class, it's all the different types defined. And then anytime
I'm inside in my methods, I'm constantly using them. So I you know, at first, I wasn't big fan
of this class based this view class component library. But I've kind of it's kind of grown on
me, I haven't talked to anyone that's used this in huge projects, I can imagine this is really
useful. And especially if you come from that object oriented programming background, I think
this makes a lot of sense, you do lose out on some of the simplicity of view just using, you know,
export default, and then using it all that way, it, this is a little bit more complicated. I haven't
dig deep dive into all the different properties, like the provide reactive inject reactive, I'm
assuming that once you get into more advanced, it's more advanced view apps, you might be using
these, there's also emit too. So if you need to like emit something to your parent, you just do
use this add emit. And then inside the component. Yeah, essentially, this is where you put everything
you put your your counts and you do your emits and everything like that. Okay, so that's all I'm
going to talk about this one. So let's talk about the other way of using class based type script
inside your view app. So let's start over again. And I'm going to use right now I'm in the YouTube
ts folder. So I'm going to go back down one directory. And I'm going to create a new app.
And I'm going to close this. And I'm going to do YouTube ts extend, extend. And this will create
a new view app, which will, this will be we're going to create a new one. But this time, we're
going to say no to the class based one, I'm going to show you what that looks like. So let's just
take a second. Okay, so it's done installing. So like the other app, we'll just change director to
it, and we'll run npm run serve. While it's doing that, let's close the folders for this app.
And we can kind of take a look at what it is. So I call it y sts extend. And in my source folder,
everything sort of looks the same. But you'll notice if you look at the bottom, you see script
Lang equals ts. And if you look at the other one, just to remind ourselves what that one looks like,
that one also had script Lang equals ts. So be aware of that. But this one looks a little
different because now we have this export default view dot extend while on the other one, we had that
decorator at the top that component decorator. So this looks really similar to what we normally see
with our normal view apps where it's export default. And then we have this object where
you put everything inside. So now we have this view extend our props look like props,
our name looks like name, our data looks like data. So let's see here. So should be running,
I'm gonna open up our app again. So here's the view just this is the basic app that always comes
with. So let's just do like we did before, we'll just delete all this crap. We'll save it. So now
we just have the hello world. So now the way this works is we have the data object like we normally
do close this. Let's see here, let's do our data object. And we'll return this object. And we'll
return a test that says hello from TypeScript. And then of course, we can put this at the top.
And we'll call it test. So if we put test in here, we look at it, you see hello from TS that works.
But let's say we wanted to add a method. So we can add a method methods here. And we'll have
a press me method. And inside that press me, we're going to we can actually give it a return type. So
we'll turn type string. And then if we don't return a string, like return a number, we get an error
that says when it's not assignable type string. So if we put in a string in here, then it works.
So you can do things like that where you now you have a little bit of flexibility with TypeScript,
you are using the same kind of way the look and feel that you normally use of Vue.js. But you
have the options of adding TypeScript in, there's a few caveats I noticed while using it, if you
actually look at the TypeScript support, it tells you the basic usage, you can use this view dot
extend, you can also use cont don't, if you just constant component, it will not have any type
inference. So make sure you always use this view dot extend. So it's a good idea that right here,
it mentions that you should probably add a type to the annotation. So like this method, you're
saying you're returning a type string. So it doesn't it gets confused with this dot type. So
need annotation due to this and return type. If you have this, it kind of gets a little bit
confused at what type it is. So it's best bet is to include it inside the type of the method itself.
So one thing I noticed, like if this works right here, and if I do return this dot test, plus
blah, that will work, of course, if I had to press me method that is. But if I let's say if
this test was a number, let's say I did this dot test and have it equal a number. Well, it gets
confused. And I just delete this block here. So the TypeScript, the annotations in here still
gets confused, it like doesn't understand this, this is a number. So it doesn't give me an error
inside the console, because it says this dot test has a type any, even though technically, the test
is a string that we defined here in the data object. So that's one bad thing I noticed.
So it definitely with these data types, it wasn't picking up that this should be a string. Yeah,
so it seems like it doesn't from the data object, it isn't inferring the, the type correctly. So
that might be one disadvantage of using the view dot extend. But you could certainly bring in your
own interfaces, you can certainly create your own objects inside each method, and do it that way,
it just looks like you have a little bit less flexibility in the data object. And if you know
of any way to get past that, leave a comment below. But doesn't seem like it's inferring it correctly
inside the methods if you do it this way. All right, that's all I guess I have to say today.
I would say if you're using the if you want to use the pure TypeScript, you might want to use
the classes. However, if you just want to add in types, I would just use the view dot extend.
And I think that would work fine for smaller projects. I really appreciate you guys watching.
Thanks.
