تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Silent UI Bug Example0:10

Controversial topic. I know first of all, thank you for not having bailed out of the course when you saw the title of this video. But what I'm asking you to do is once again give it five minutes. We are going to go on a little journey together. So we have our data here and let's say that for some reason the trade field was renamed to Vibe, the data lives in its own file. Maybe another developer changed this without realizing

renamed to Vibe, the data lives in its own file. Maybe another developer changed this without realizing that it might impact the ui. And even when looking at the ui, everything seems to be working properly until you realize that the character trait that used to be here is no longer. Of course we know about this because we've just made the change, but this sort of stuff can happen. Even if we had the dev tools open,

but this sort of stuff can happen. Even if we had the dev tools open, there's no error in the console and that subtle bug really might sneak up on us. And that makes sense. We have these puppy cards that expects a puppy and is going to have properties like id, name, image, path, traits, but there's really nothing in place to enforce that right now. We're just hoping that the developers will know what

Why Use TypeScript1:02

to enforce that right now. We're just hoping that the developers will know what to do and do the right thing. Now before I talk about TypeScript, yes there is a prop-types package that you could use, but as you can see it's been published three years ago. The last time it used to be in React Core and got moved externally about eight years ago. And really the industry as a whole has moved towards TypeScript.

And really the industry as a whole has moved towards TypeScript. So if you wanna work with React, you're going to see TypeScript left and right. And so I suggest that you get used to it. Once again, I wanna be super clear that you do not have to use TypeScript, but I personally suggest that you look into it and hopefully what I'm going to show you now is going to help you make the first few steps towards enjoying working with TypeScript.

Add TS Config1:36

to show you now is going to help you make the first few steps towards enjoying working with TypeScript. I am going to rename the puppies.js file to the TypeScript extension, which is .ts. Okay, so doesn't seem too happy about the change. Uh, it's looking for a tsconfig.json file. So just like we have eslintrc config and vite.config, we need to add a TypeScript config, tsconfig.json file to our project. And I'm going to paste some options.

that JSO file to our project. And I'm going to past some options. You don't need to understand all of these. Uh, quite often it'll be generated for you in a project, but with that in place, we should be good to go now. So nothing has changed in our file. This is still JavaScript. TypeScript is a super set of JavaScript, so any JavaScript is valid TypeScript, but then we can add annotations to our files.

Define Puppy Type2:22

so any JavaScript is valid TypeScript, but then we can add annotations to our files. So here I will define a type called puppy and it's going to basically be an object or essentially a declaration of the keys for each puppy object and their type. We have an id, which is a number. Then we have a name, which is a string, a vibe, which is a string and an imagePath, which is a string. So we now have defined a puppy type and we can go and use it

which is a string and an image path, which is a string. So we now have defined a Puppy type and we can go and use it and mark this puppies array as an array of puppies. And the way I do that is I add column next to the variable name and I will set this to be a Puppy, but this is not a single Puppy. This is an array of puppies. And the syntax for this is an array opening, closing array brackets. And just like that, I've defined my puppies to be an array.

closing array brackets. And just like that, I've defined my puppies to be an array of types. If I go and change the type properly on the first one back to trait, we are instantly gonna be notified that something is not right. You can't pass properly. Traits to type puppy traits does not exist in this type. Or if we had no trait at all, now the whole object doesn't match.

Or if we had no trait at all, now the whole object doesn't match because the property vibe is missing on the type that is defined here. To expect all of this, this is not going to break the UI or prevent it from working. You can see it still works without working properly. But something that's quite common is to set up a check step in your deployment pipeline where you check for TypeScript errors.

Add Type Check Script3:49

to set up a check step in your deployment pipeline where you check for TypeScript errors and if any you've stopped the bill and you just fail. So I'll go and package.json here and set up a check script and I will just run tsc, which will basically run the TypeScript checker on the project in my tsconfig. I will just add the include src to tell TypeScript to look inside the src folder and I'll now try to run npm run check and looks like it quotes the error on the puppies file.

inside the src folder and I'll now try to run npm run check and looks like it quotes the error on the puppies.php file. Line nine property vibe is missing. All right, so let's go back to the puppies.php file and add the correct vibe property and I'll try run the checker one more time and we should be all good. Nice. So we've seen that the puppy type is already useful at the data object.

Type React Components4:36

Nice. So we've seen that the puppy type is already useful at the data object level, but let's now export this type of puppy and we'll go in the PuppysList component here. And here I will import the puppy type from data/puppies. And now what I want to do is annotate my PuppyCard components to be of the type puppy. So before I can do that, I need to change the extension here in my puppies list to

So before I can do that, I need to change the extension here in my puppiesList to .tsx. So it supports TypeScript. There we go. And so there's a couple of ways you can define the types. Probably the most readable and explicit would be to set your type here, PuppyCardProps. Yeah. And so the PuppyCard takes a puppy prop and it's a Puppy type that we've defined and imported.

Yeah. And so the puppyCard takes a puppy prop and it's a Puppy type that we've defined and imported. And so now once again, I've defined it and I can with columns, assign it here, puppyCardProps. And so with that in place, what I'm expecting if I scroll down is to instantly be notified that this trait is not correct. That was the sneaky bug that made the trait disappear here silently. And now that we very simply annotated our puppyCards to be

that made the trait disappear here silently. And now that we very simply annotated our puppyCards to be of the puppyCardProps type, we are instantly notified and if I hit the sidebar open, the file name would go red. And like I mentioned before, if we were running the check, it would get codes there. So as you can see, that really limits the risk of bugs making it through your application. Another amazing thing that TypeScript brings to the table is the autoComplete dx.

Another amazing thing that TypeScript brings to the table is the auto complete dx. So if I delete trade, it's going to tell me what uh values are available. We sort of already had this before through the magic of VS Code, but now with TypeScript in place, it's going to be much stronger and much more useful. So here we want to use puppet vibe and we fixed the bug and the trait vibe is back in our ui.

So here we want to use puppet vibe and we fixed the bug and the trait vibe is back in our ui. Honestly, that's pretty cool, right? Outside of the TS config setup, which is set and forget, there wasn't much work to do at all. We've just defined a type and then annotated it in our data and in our components. So I showed you that you can define the type like this explicitly and then pass it here. But you can also short circuit this.

explicitly and then pass it here. But you can also short circuit this and basically pass just that part here. So I'll leave that one like this. And for the puppies list at the top, I'll show you what I mean. Instead of setting a type IES list props like this, I will directly here have the object which has one property puppies set to puppy. And so this is one of the most common way

puppies set to puppy. And so this is one of the most common way of defining types on the React component that you'll see. Arguably it's a little bit less readable for newcomers than to have a defined type and then past here, but as you get used to it, that has the benefit of not having to name something just to use it once. Alright, let me show you something pretty cool in the data file. I will intentionally omit

cool in the data file. I will intentionally omit by commenting out the first name frisket. And so of course TypeScript is going to tell us instantly about it, but I will remove the type and enforcement here and just let puppies be itself. So now we're not catching the error here, but if we look at the ui, we indeed have a problem. The name frisket has been removed on the first card in the puppies list, we are defining the puppies list type.

The name frisket has been removed on the first card in the puppies list, we are defining the puppies list type to have that type of puppy. We say here that's an array of puppies and then the puppy card is a puppy. So I sort of expect TypeScript here to work out that one of the puppies is missing the name property. But if we look at our component tree by going to app.jsx turns out that the place where we are assigning the puppies into the application is

that gsx turns out that the place where we are assigning the puppies into the application is in this puppiesList file. Now puppiesList is expecting to be an array of puppies, but this is currently a JSX file and TypeScript cannot run its thing in here. So if I change this to TSX and I save instantly, you can see that we are now made aware that the puppies array has an issue. The property name is optional, as in it's not passed in one

that the puppies array has an issue. The property name is optional, as in it's not passed in one of the objects, but it's required in the puppy type. Once again, the error is not being caught in the puppy's list component because it's being caught higher up where the puppy's list is trying to pass this array of puppies which doesn't have the correct shape based to the puppy type. And so if we go in the data and we fix that type script is back to happy.

Refactor Types and Convert TSX8:45

And so if we go in the data and we fix that TypeScript, it is back to happy. Nothing is read and the app should be back to normal and it is alright. So hopefully you see at least the potential helpfulness of TypeScript here and later in the series when we do some refactoring, I think it's really going to shine. To wrap up this video, I want to do two things. I'm going to move the puppy type into its own types directory.

I'm going to move the puppy type into its own types directory. So I'll make a file called types, this is the folder name, and then let's go index.ts for now since I don't think we'll have too many types set up. And so here I will export the puppy type from that index file. And I love how the red color codes tell me where I have to go and fix things here.

And I love how the red color codes tells me where I have to go and fix things here. We need to import the type of puppy. And by the way, I think that some ESLint stuff auto changed this for me. You can import a type like this, but it's common practice and recommended and sometimes enforced to mark it as a type. So here we want to fix the import path to be types. Alright? And the next thing I wanna do is change all the other components from JSX to TSX.

And the next thing I wanna do is change all the other components from JSX to TSX and see if we can catch other errors. I don't think we will, but that's also going to set us up to just be able to benefit AHA here. One error. Uh, where are we up here? Uhhuh interesting transform that tools may have fumbled at once. So this actually fieldset, I want it to be disabled because it's for a file upload,

So this actually field set, I want it to be disabled because it's for a file upload, which I don't wanna handle until later. Let me check in the static HTML that we've copied. So I'll search for profile and here we have the disabled attributes set to the field set. And so with this empty string here, I actually believe that the field will not be disabled. So let's scroll down to the form and here try to click

that the field will not be disabled. So let's scroll down to the form and here try to click and yep, this is not disabled. So what we wanted here was disabled just like this or disabled equals true, but really just the attribute itself. And now I should not be able, I'm clicking frantically to select a file. Alright, well thank you TypeScript for catching another issue.

Alright, well thank you TypeScript for catching another issue. Alright, let's continue. Header, that's TSX and container, that's TSX and I think that's all the components, but we also want to have our entry file here to entry that tsx. And I believe for that one I'm going to need to update the index.html because we say JSX and here it's going to be TSX.

to update the index.html because we say JSX and here it's going to be TSX and we should be good to go. And we indeed are, even if we somewhat have a fairly lightweight use of TypeScript here, it's already proving useful. So for good measure, let's run the type check one more time and then we can move on. Alright, npm run check and looks like we good to go.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟