TypeScript in React - COMPLETE Tutorial (Crash Course)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you want to be a react developer these days you also need to know typescript typescript has become a defao standard in react applications in this video I'll show you all the typescript things that you need to know as a react developer so right now you can see I have a simple button component and it's using the jsx extension so if you're ready for this let's convert this into TSX I'm going to say this button now needs to start using typescript you can see when I do that it immediately changes this icon here I'm going to press enter and now we have enabled typescript in this file so let's start off with the most common things you want do in typescript let's say we have some kind of variable I can just write a variable like I'm always doing in JavaScript but now if you hover this variable you can see that there is some type connected to this and we have not specified this type ourselves we could do that we can say this URL is going to be of type string you use the colon and then the type we could also say number and then you're going to get red squiggly lined because now we're trying to assign a string to a variable that we just annotate as a number so it should be a string but you don't have to do this because TCP is smart enough to infer from what you're assigning to that variable what the type is going to be it sees that you're trying to assign a string to this variable so it will automatically infer this variable to be of type string so we don't need to specify that now what's the benefit of having that type well now later if I try to assign some other value to it that's a different type I'm going to get a warning a r squiggly line from typescript I'm trying to assign a number now to a variable that's supposed to be of type string so typescript is helping us out here it's telling us this is probably not what you want to do besides variables we also often want to type functions let's say we have some function here convert currency and it will take two arguments let's say an amount and then also the currency that we want to convert that amount into and then here in the function body we would have the actual implementation now in the function body typically we don't want to type anything but we do want to type the function parameters if you don't type them actually we're going to get red squiggly lines here we're going to get a warning from typescript because it can't infer anything here and we haven't specified it ourselves so by default it's going to be of type any which is not what we want any means anything goes we can do whatever we want with it it basically defeats the purpose of using typescript in the first place if you're using any we do want to type this as specifically as we can so the amount is going to be of type number let's say and the currency can be a string USD EU for Euro so then I can call that function convert currency with for example the number 100 and then a string if I now make a mistake here if I now type in a string as the first argument you can see T War says hey you're trying to pass a string here but it's expecting a number type right so T is helping us out out here it prevents us from making this mistake also if I try to pass in another number here as the second argument typ scale is telling us nope that's not what you want to do you want to pass a string here and then we can also specify the return type this is usually not necessary but sometimes you want to do that so if you want to specify what this function should return maybe it should return a string let's say then if you call that function you're going to get back a string I get res lines now because I'm not returning anything here in the function body because it's just an example all right so now let's talk about how you can use this in react so in react we have components and these are actually just functions like we just saw except you write a name with a capital case and in the world of react we call these parameters props so typically you're going to get props here and just like before we want to type those parameters we want to type the props and we don't really want to type the return values so with react components typically the only thing you want to type are the props now in the past people often did the following to type components so if you had some component function and then to type it people would use colon react. FC and then in here you could specify the type of the component props this looks a bit complicated but this is how it was done mostly in the past you will still see this sometimes but there are some issues with this FC and therefore it has gotten out of fashion and it was also only possible to type this if you wrote your component function like this so as an arrow function you can still do that of course nothing wrong with it personally I prefer this traditional function syntax for a component and let's say that our function is going to receive some props so I have added the button to our page here I'm using the component and now let's say I want to be able to pass let's say the background color I want to be able to set the background color when I use this component right maybe I want to be able to set it to Red so I should be able to pass in this background color prop but if I do that now I get a warning from time descript because TPT is telling us you're not accepting any props so now we need to actually accept the props so we have props and that's just an object that holds all the props so if we want to get the background color from there we can do props do background color right and then we can use that background color here in the class then to change the background color let's say but let's focus on time script in video so now we have props but we haven't typed this so to type this we can use colon and now it's not going to be string or number because props is an object to type an object we can just use curly braces and then we can say in there there's going to be a property background color and that one is going to be of type string so if I do this this is now properly typed the props is an object and in there we just have background color as a string if I not try to pass a number let's say number five we get an issue from tcri and T script is helping us out you have to pass a string here now typically you don't write your reactor components like this typically you destructure this so here you can destructure it like this so instead of doing props background color you can just write props and then just destructure it from props like that or just immediately here in the parameter list immediately destructure it here and that's actually more common so instead of writing props you can actually already just immediately write that destructuring in the parameter list like this so this is a more typical syntax that you're going to see in react components so the props here it's still an object but we are immediately destructuring it here and therefore we should still describe this as an object now let's say we want to pass a font size as well so what we want to be able to do is say the font size should be some number let's say maybe font size should be 30 and we get red Sly lights because we are not accepting a prop called font size here so here now we need to accept a prop called font size and we are immediately going to destructure that here but we also need to specify this to typescript we're going to tell typescript hey we expect a font size and that's going to be of type number and the benefit of this is now when I try to pass something like 40 pixels let's say which is pretty common mistake that you could make here task is going to tell us hey don't do this you should pass a number here right so you can already see typ is helping us out here it's preventing us from making mistakes so we have the type string type number and the third common type primitive is Boolean so let's say we also have some Boolean we want to be able to specify whether this button should be a pill shape or not so we could say pill shape should be true let's say so now we need to accept a pill shape here so will'll say we're going to destructure that pill shape from the props and then we're going to specify it here for time script we're going to say this going to be a Boolean true or false now you can see the syntax here is quite ugly it looks like we're sort of repeating ourselves so we have curly braces here with all these props and then we sort of have the same here it looks like the same thing so it's bloating up our components here quite a bit especially if you have many props so instead of writing it in line like this maybe we should extract this into a separate type we're going to create a separate type so in tkp we have type Ty and we can call that let's say button props I like to use the name of the component and then just add props and we can say well this props was going to be an object with all this stuff here all these properties so we can just paste this here and now we can use this name instead of writing it in line we can just specify this name here you can see now it's much cleaner it works the exact same so the benefits are tab script helps us prevent mistakes but it goes beyond that let's say we don't know the properties that we can pass here I'm using the button and I want to see the options essentially so I can press control space here and T SC is telling us these are the properties that this button can accept we have background color of type string we have font size of type number and we have this pill shape of type Boolean so I get this very handy intellisense as well when I remove these now by the way we see red quickly line so if we look at this we can see there is some problem here so we are not passing anything here and that's a problem because the way that we've done it now is that we have made these mandatory so if I add two of them back we still get this red Squigly line because we are still miss missing one which is pill shape we don't have pill shape here but the way that we've done it now is that these are all mandatory so if we miss one we're going to get a warning I can make them optional by having this question mark here so now if I go back you can see the rest quickly line is gone because the pill shape now is optional another benefit of typescript is that let's say I want to use some method here on the background color variable this is a string so if I do this two upper gas this works without problem but if I try to do the same thing with font size which is of type number I get a warning here because two uppercase is a method that doesn't exist on type number TP scpt helps us out with using these methods as well if we don't type this so if I just remove this this font science is going to be of type any by default and sometimes you will also see people make that explicit so they'll say this font science is going to be of type any so any means anything goes so when I do this now suddenly I don't get red Squigly line here so now I could be passing a number here and I'm trying to do dot two uppercase but this would cause an error it could cause our application to crash it could cause a lot lot of bugs in our code and that's the problem with the any type any means anything goes you can do whatever you want but then why are you using typescript in the first place right so we do want to type these things as specifically as we can so here when I type it as number again you can see we get a warning so we can fix it so let me remove that we are not typing the parameters of this component do we also need to type the return value of this component so it's returning this button here this is something called a jsx element this button here we don't have to type this ourselves so if I remove this and just hover button you can see it's already inferred that we are returning this jsx element so typescripts can infer a lot you just have to follow the red squiggly lines let's talk a little bit more about the other types that we have in typescript instead of accepting any string for the background color maybe we can be more specific than that maybe we only want to allow the string red or the string blue or the string green so you use this pipe symbol and this entire thing is called a union type and it's possible that we want to use that for other properties as well for example we may also have a text called color prop and maybe that one needs to accept the same strings now we are duplicating ourselves so what we can do is we can extract this out into its own type so we can have another type here and we can simply call that colors and that's going to be the union type now I named this colors the plural but typically it's actually better to leave this as the singular name so the color is going to be either red blue or green and then we can specify color here right so you can extract new types like that and just combine them like this now if I want to make a change here maybe add another color or other colors I only have to change it in one place now because I added text color here and I didn't make it optional so now we're going to get red squiggly lines here because I'm not passing text color so let's say I make text color the string purple now we get rid of the red squiggly lines all right so what about arrays maybe we want to accept a padding prop and with padding you have multiple sides right so you have top right bottom left so maybe this can be some kind of array so what we can do is something like this so it shouldn't be just a number it should be an array aray of numbers you can just tack on these square brackets and that means it should be an array of this type I can do the same thing here and now it's going to be an array of Boolean I can even do it with my own custom type right now it's going to be an array of these colors and for petting now I need to pass it in so how does that look like Well for pading now I need to pass an array here so it's going to be square brackets and it should all be numbers right so if I try to do something like five pixels 10 pixels TP is warning me hey this shouldn't be in this format it should be a number right type string is not assignable to type number so it should be 5 10 20 50 now the problem here is I can add even more I have not restricted the length so there is another type and it's a bit more rare it's called a tle so instead of writing it like this you actually want to write it in the array so if you just specify number number number like this you get a so-called Tuple which is basically just a more specific array right so Tuple is not something that you heard about before as a normal JavaScript developer but in a world of typescript it basically just means an array but a little bit more specific than that so basically you specify how many there should be and in what order what specific types there should be so here we just have four numbers so now if I try to add more than four I get a warning from time script so I can fix the problem right so I just have to remove these now I have four elements in the array and now this works as well of course I should also accept it here in my actual parameter list right so now we add a text color as well as padding all right so I'm using Tailwind here but let's say that we want to use just plain Styles we of course also have the style attribute and here you can pass an object so I can have another curly braces here and here we can set background color to the background color that we pass color to that text color font size you know we can deal with the petting like this actually co-pilot helping me out here right so we can process that array of numbers into an acceptable format here and we can have many more properties to deal with all sorts of CSS properties that we can add but that's a lot of work so instead of doing all of these CSS properties individually how about we will just have one style object and then instead of having all of this individually we're just going to use that style prop here so we want to be able to accept an object now so let's remove this I'm just going to remove all of this so button props we now are going to have this style and the style is going to be an object so to describe an object we have curly braces and then we could have background color font size Etc text color and I could specify this object like this and then here when we use that object let me remove all of this now we need to pass one object here for the style prop so we have jsx syntax jsx curly brain and then we have the actual object that we want to pass that's going to be background color font size and let's say text color and this is how you type an object and actually the props themselves are also an object so that's also why we have curly braces here now of course we can have hundreds of these properties and it would be very cumbersome to specify all of them individually like this so we also get some help from react so we also have some types that we get with react here out of the box instead of specifying our own object we can just use one of the types that we get from react theater so we can say react react. CSS properties right so now we're not specifying our own object react is now specifying the object for us right so just like we had our own type for color right so we had our own color type we also get some types here when you work with react just to help us out so now we can pass any CSS property that we want and text color is actually not a CSS property it's actually just called color in CSS and then we can pass padding for example border radius and we can pass border color and let's say I make a mistake here I pass a number we get a problem because the CSS properties will specify that you need to pass a string here not a number right so it needs to be some string that's how you can deal with Styles efficiently so this is describing style all right so style is an object and sometimes when you work with objects you're going to see something else as well so let me remove all of this let's say we just want to have one prop for Border radius right so border radius means this curve corner right and it's could be top left top right uh bottom right bottom left so basically you have four possible values so what we want to be able to pass is something like this a border radius and maybe the should be an object and maybe we want to have let's say a key being top left that's where we start and that should be some number let's say five and then we have top right should also be some number and then maybe bottom right that should maybe be a little bit more and then we have bottom left so this is an object that we're passing here that has string as a keys and it has number as values how would we type something like this when I save here by the F pretor automatically removes the quotation marks here but these are still strings for the keys how do we accept this and now we're going to have a border radius object here how do we type that well we have border radius and now you could say something like well we're going to have all of those properties right top left is going to be a number top right is a number but now we are only specifying the value for top left we are not specifying specifically what top left itself should be and so sometimes what you're going to see is something like this you're going to see record and then you specify the type of the keys and the values so for the keys you're going to have string and for the values you're going to have numbers right these are going to be strings and these are going to be numbers sometimes what we also want to do is we want to pass a function for example we want to do something when you click on the button we have that function for that specified not in the button itself but here and we just want to pass that to the button so maybe we have some onclick and that can just be some you know onclick Handler I will just leave this as an empty function for now so now we're passing a prop here called onclick so let's go to our button here and now make sure that we accept this so now we're going to get something called on click here we want to accept on click and then we can remove this style and then of course we want to put that on the button itself so when there is a click on this button we want to run that function that we get here but how do we type a function here a function as a type with prop well you just have this syntax so basically like an arrow function so here you specify the parameters well this function doesn't have any parameters and then you have this fat arrow and then you specify what this function returns this function right now doesn't return anything so you use the word void if a function accepts something let's say it has one parameter called test and maybe it returns a number let's say number five and this test is a parameter so we also want to specify here when we create the function let say it's going to be a string now it has one parameter of type string just going to have a parameter called test it's going to be of type string and this will return a number so instead of void we would say returns a number all right so let me also remove this one of the last things I want to show you here for the props is the following so right now we have this button and we are just using this without closing tag but in the real world instead of hardcoding the word click me here maybe you want to be able to specify it here as you use the button so you would use the closing tag here and then here maybe you want to specify it here click me now we're going to get red Squigly lines because it's it's talking about children so if you have something inside your opening and closing tags of your custom component that's called children it's actually just a prop that you get so then we have to accept it here so this is called children and that's just how react works that text is just going to be assigned to children so instead of hard Cod and click me here we can just output that here so now if I save you can see I added this exclamation mark but we also need to type this so how do we type this so here we can specify children it's going to be a so-called react node so in react we have these elements jsx elements but we also have plain text and we also have let's say booleans and this react node basically allows all of those types to be passed in whether it's text or I have some other elements elements here that I pass so if I pass just an empty div you can see that also works so if I save here and I save here this also works now of course this doesn't make any sense but this react node is more General is quite a general type essentially maybe you don't want to allow so much to be best maybe you want to be more specific because maybe you only want to allow jsx elements a jsx element can be for example an icon in this context so maybe we have some icon I'll just leave it empty for now but let's say we have icon now and that's going to be this this is so-called jsx element just like div is a jsx element span these are all jsx elements and let's say in this button we want to pass this I icon here and I have to use C braces here so now I'm passing icon here which is a jsx element you can see we don't get any errors because react node allows everything to be passed but maybe we only want to allow elements to be passed not text not booleans only those jsx elements so we can say well this children should be a jsx element now you can see this this also works but now if I go back and I try to add text here if I not try to add text you can see we get a warning from tvcrip because it says something about doesn't accept text as child elements because jsx element is more restrictive than a react node now in practice you do want to use react node most of the time so let me change this back if I save here click me we do typically want to have react node here all right sometimes you're also going to have some state so let's say we are keeping track of the count but we're keeping track of it in the parent component let's say this happens sometimes so here I have some new States let me import this and I'm using nextjs here so when you're using these client side hooks you want to convert it to a client component so let me me just do that it's not important here for typescript what we want to do now is when we click on the button we want to increment the count so we want to pass this set count function to button right this is quite common that you pass a Setter function like this so now we need to accept this so right now we're not accepting that so here instead of children let's just hardcoded for now click me and now we need to specify what we're going to get with this set count now I get a suggestion here from Coop pilot which is actually correct and this is a very intimidating weird looking type and the good news is you don't have to memorize these we'll talk about hooks more in a second but here for example if I didn't have co-pilot I could just hoverer this and tasket will already tell you what type this is so you can just copy that type and specify that here basically it's a so-called Setter function and it accepts only a number so here when we call set count we have to pass a number here if you pass in a string you're going to get a warning from tcri right and here I have to remove children now because we're not accepting children as a prop so let me do this self closing tag again okay so now we got rid of all the red squiggly lines all right so last thing I want to show you here is default values and you you can have a prop with a default value and if you specify that in line and if you do that I can remove all of this maybe we just accept the count and initially this count is going to be the number zero if I do this now I don't have to type anything because if I hoverer this types scpt can already infer this count to be a number it can just look at this and it can see oh this is going to be a number type if you have default values you don't need to specify the type let me also remove this and this as well all right let me remove this and let me remove this as well so so far I've been using a type Alias as it's called so here we have button props and props are an object and in an object we could have text we could have some amount we can have count it could be a number this is called a type alias in TP script we also have interface I could have also written interface button props so let me comment out the type Alias for now so we have interface and then we also have braces here but you don't have the equal sign here right so here with type Alias you are sort of assigning something to this type here we don't have that and then we have text is string count as number and in this case this is the exact same we're also describing an object with text as a property and count as a property and what some people do is if you have an interface they write the character I in front of the name to indicate that it's an interface and some people also like to put a t in front of the type Alias name so you will have t button props it's a bit less Comm these days I don't do it myself so why didn't I use the interface well interface has some issues for example with interface you can only describe an object so if I have some URL here for example and I want to specify that as a URL type well I can easily do this with a type Alias I can just say that's going to be a string right I have the equal sign and I say that's going to be a string but how would I do that with interface if I do interface URL I cannot do that equal sign right so this will not work so with interface is you're always describing an object and then in here of course I could say URL is going to be a string but now this is an object this is just a plain string so this will work only if I actually make it an object like this right so that's the first problem with interface you can only describe objects and in the real world you actually do often want to describe other things as well for example we saw a color type so we had type color and that was this Union type so we had a type of color with red blue green and this is a union type you cannot do this with interface so interface color I cannot do that equal sign so immediately I have to describe an object essentially and this is an object and this is just a PL Union type so it's pretty much guaranteed that you're going to use a type Alias at some point because interface cannot do everything and since you're always going to use the type Alias at some point why not just make type Alias the standard the default so that's what I do I only use type Alias and I never use interface so in this video I will focus on the type Alias but other people may use interface so I will still show you how inter interace works as well as we go through the topics so here we're creating a button component and a button can have many attributes like type is submit or reset and it has other things as well like autofocus and it has many other attributes I can hold control space and you can go through all the attributes that this button can have so when we use this button component we may want to use those attributes so here I want to be able to specify for example that the type should be submit let's say and that it should have autofocus is let's say true and these are two typical attributes so now we need to accept that here so we need to accept these as props so we need to accept a type prop as well as autofocus prop and then we can type them individually here should be reset or should be submit or reset or button and autof focus let's say should be optional that should be a Boolean and then of course I do need to specify that the props is going to be of type button props right but now we only have two we can have hundreds of these attributes so what you basically want to do is when you have a custom component as essentially wrapping like a native element you basically want to allow all those attributes to be passed as a prop and we don't want to specify all of them individually one by one so here's another example of where we can use a helper type so what we get here when you use react is you also get the component props type and then in the angled records you can specify which element it should be well here we're using a button element and when we do this you can see we can accept type and autofocus we don't get red squiggly lines here we can now accept all the attributes that this native button element accepts this is especially helpful if you're wrapping an an element like button or maybe anchor tag if you're creating a custom link component right so then you can just use a and now you can accept all the attributes that an anchor tag can accept like a draft and ALT Etc right or image and then you can accept all the props here that have to do with image uh source and ALT all right now we get red quickly lines here because this should be on the namespace react so these helper types are our Nam space based on react so you have react. component props the name spaces that's more of an advanced topic that's not important to understand right now now you can use this but when you look at the description here it does say note prefer component props with ref if ref is forwarded or component props without ref when you don't accept refs so sometimes of course you also want to pass ref right so here you may have used ref and then you want to pass that ref to a child component like this if you do this basically ref ref now does become an argument and we need to type that as well so if you want that you need to use with ref so then you also get ref however here we don't want to do that so here we want to use without ref right so instead of plain component props they recommend that you make it explicit whether you're accepting the ref or not in this case we don't so we say component props without ref some of these type names are a bit long and confusing but you'll get used to that as you practice a little bit so now in our button component we are destructuring type and autofocus but we can have all these other attributes as well so should we specify them all manually one by one here and the answer is no so in JavaScript we also have this rest operator and you can call that rest or maybe props I will just call it rest and this will just wrap everything else that you pass here in an array so if I pass something else here like default value and last name all these potentially hundreds of other attributes that I could pass as a prop here I'm scooping them all up with this rest operator and this will essentially just become an array of all of those props now and then we just want to spread that here on our native button element and you spread here also with three dots and we can just spread that here and here we would also specify the type so type is going to be submit or reset autofocus is going to be autofocus Etc and then you would spread all those other props there all right let me clean this up a little bit so now we accept all the attributes that a native button element can have and nothing else but what if we do have something else that's maybe not an attribute here but we do want to accept it as a prop well we we can intersect so you have the m perent and then the additional stuff that you want to add maybe we do want to have some kind of variant prop maybe this button can be a primary or secondary button and let's make it optional so now we accept all the attributes that a native button element can have and a variant prop as well so now we can also get a variant prop here which we can then use to maybe style this as a primary or secondary button so let me actually clean this up a little bit let's go back to a clean slate here for a second let me remove all of this stuff as well so we could have a type for button props here so button props could have let's say type and color red blue green and then maybe we have another component and we need props for that component as well but that's going to be let's say a super button so a special buttons essentially which accepts the same props as a normal button so we can say button props but then also something additionally so we can say we can intersect so we have and the additional stuff here maybe this one accepts a size prop that the standard button does not accept but the Super Button does right so it makes sense right you just have like a base type and then you can add something to that and with interface you would do the same with extending so let me change this to interface button props and here we have Super Button props so with interface we don't have this equal sign how would we then add something here well you use the extends keyword so here you have the extends keyword and not this m% so let's remove this so now we are doing the same as here and so you're going to see this sometimes you use extends with interface and you use the m perent with the type Alias this is called extending this is called intersecting so let me remove this and this as well let me also remove this let's talk about event handlers so on a button you can click and maybe we want to do something right so you have an event handler and could also be on change and I could specify the Handler the function that you want to run when that event occurs in line here so maybe I just want to log something this is a function and usually we type the parameter we have not typed this parameter e or event ourselves but if you hoverer it you can see it's still typed it's typed as some very difficult type here react. mouse event and then with the weird angled bracket we don't need to memorize this this is automatically typed by typescript because typescript has context here it can see that we're defining this function here in this onclick attribute it can infer the type for the event from that however if you have the exact same function extracted so here you maybe have a function here called handle click and then we have the exact same function here and then we pass that here here that's not the case so now tasket cannot just easily infert a type for event here because we could use this function elsewhere as well tasket doesn't know that we're only going to use it here it now doesn't have the same context as before so now we need to type this ourselves and how would we ever know what the type here is going to be it was a very difficult one right now what you can do is you can just hover it so here you can go to the inline version again and you can just hover the event and you can just copy that difficult type so I'm just going to copy the entire thing and now I can write my handle click function up here with this type so I just have colon and then just paste a difficult type and now this is also properly typed and of course I can pass handle click here right that's how you deal with event handlers in typescript in react same with unchange onsubmit and these other events all right let's talk about Hooks and typescript let me remove all of this so of course we can also have hooks let's say we're keeping track of the count and I like to import it separately so let me import it like this all right so now we have a count variable which if you hover you can see has been inferred as a type number so typescript can see what you're passing as the initial value and it can infer what the type is going to be so here it has correctly infert the type so we don't have to do it ourselves if you want to do it yourself you can use angled brackets you can specify the type like this and then indeed count is still a number if you would do something like this if you type it as a string typescript will now complain because now the initial value that you specify is not a string here we specified that this count should be a string and now we're passing a number here so you could do this you could make it explicit but it's not necessary TK can already infer it from that and that's why you don't really see many developers do that and same with string so I can have let's say yeah let's say text I could specify that this is going to be of type string it's not necessary if I leave it off and hover text you can see tabp has properly inverted to be a string same with Boolean is this the primary button we're passing in a Boolean here and tab script can infer from that that this is indeed going to be a Boolean type I could specify it like this if I want but it's not necessary it's not wrong it's just not necessary these are all primitive values but it's different when you have an object type so let's say we just have a user object and we have set user now initially often with these objects the initial value is going to be null because maybe you need to fetch the user first so initially it's going to be null and then after you fetch the user you're going to set the user and it's going to be an object but now when I hover User it's typed always as null so if I want to do something with that user for example I want to get the user.name TPT will complain because user is null and on null you don't have that name you don't have anything on null with an object you want to specify the type of that object so this time you actually do want to use the angled brackets and now we don't have you know an outof the boox type like string or number or Boolean we have to create our own type so we can create a type called user let's say and then we can Define that up here we can say type user and that's just going to be an object with maybe a name an age and other things now when I have a user it is of type user and I can safely access that name here now now when you do that you do get another issue which is we are passing a null we have just specified to time script that this user is going to be of type user but now suddenly as an initial value we pass in null so T is telling us hey why are you passing null here it should be of type user it should be some object with name and AG well that's simply because initially it should be null we're still fetching the user initially it's going to be null and once we have fetched the user we're going to set the user so initially it should be null to work with this what you often want to do here is you want to say this user is going to be of type user or no so initially it's going to be null and eventually it will be of type user now this user is going to be of type user or null and that means it could be null so when you try to access that name well you have to be careful because it's possibly null you cannot just access that name so if you do this and user is indeed null you're going to get an error your application May crash so what you often want to do here is use optional chaining if user is null and you're trying to access that name now it's just going to be undefined and you you're not going to crash or have these errors so those are types when you use use state the other hooks we have is use effect for example with use effect itself you don't really need to type anything the other hooks are for example use ref with use ref you sometimes do want to type something so here for example if I have use ref maybe we want to get a reference for this for this native button we can pass that ref like this and we can pass the initial value null and let me import this now of course the initially the value is going to be null if I hover here you can see there's ref is some null ref but of course we know that eventually it's going to be this button HTML element once it's it's been properly attached so here we also want to specify what type it will be eventually so here we get some helper types again from react so there is the general element type but we can be more specific than that there is also something called HTML element but we can be even more specific than that it's going to be an HTML button element but now this ra will be properly typed and here we don't have to do or null because us ra Works a bit differ here with types the only other hook where you need a lot of typing is when you use the context API it's too much to handle in this video I have a separate video on that now I want to show you some quick tips and tricks let me clean up a little bit here I will remove this and this let's say we have some constant button text options click me click me again and click me one more time now maybe you want to do something with this just as a silly example maybe we just want to map over that array so we can say button text options map and for each option we want to do something maybe just put it within the button when I hover option now you can see that an option is being being inferred as just a string and that's because well when we hover this button text options variable it's been inferred as an array of strings which makes sense when you look at it right what's wrong with this it's not necessarily wrong we can just be more specific so what we can do is we can use as const this is not JavaScript this is purely typescript and what this will do is essentially make it more specific than just generally an array of strings it's now specifically going to be this array only we're not going to add anything it's going to be read only and it's not going to be you know any string in the array it's going to be specifically these strings that's often what you want to do when you have these constants in a react app maybe you have a set of links for example just TCH on as const so you make it more specific than just a general array of strings it's going to be specifically these strings the advantage is now when I H option here I get the actual values for the option so I know what the actual values are going to be instead of some general string and now it's also read only which means if you trying to add something typescript will warn you all right let me show you another trick let's say we have some user type and this user maybe has a name and maybe also a session ID right that could be a user type and maybe we also have a guest type but this guest should be very similar to user the only difference is we don't know the name of a guest the guest hasn't registered yet but we do have a session ID so what we essentially want is just the user type minus the name so we have the omit utility and then you have the angled brackets here these are sort of arguments in the world of typescript and we can say take the user type and omit the name name from there let's say when we do this and you hover guest you can see guest is just a type with only session ID and not name right so omit is helpful if you want to take an existing type and you want to remove something from there all right one more quick tip let's say we are storing something in local storage and when you want to get it out of local storage again usually you're going to use the use effect hook so use effect itself you don't have to type anything here but sometimes in here you do something where you do need some typing so if you want to get let's say the previous button color maybe we store this in local storage so we can say local storage get item button color maybe we already have a type for this so maybe we already have type button color and it's going to be some Union type like this and this button color of course should be just this type however typescript iners this to be just a string or null we can sort of assert we can say as button color so now when I hover this you can see this is of type button color which makes it more in line with the rest of our app that is using this type right so you can say as you basically assert to typescript that you know better than typescript it's going to be this type there's one Concept in typescript that a lot of people are scared of but you don't need to it's called generics let's say we have some function here convert to array and the only thing that this function does is it takes in a value and it returns that value in an array so just square brackets and we just put in the value like this and now we want to be able to call this function with for example the number five but I also want to be able to call that function with let's say the string hello I should be able to to call it with different types and we get red quickly lines here because we haven't typed this value parameter it has an any type now so what's the problem with an any type well the any type means anything goes so I can do whatever I want now with this value so I can try doing two uppercase and I don't get any errors but this is only something you can use on a string so if I pass in hello this will be hello. two uppercase no problem but if I pass in the number five it becomes five to uppercase this will give us an error it may cause the application to crck two uppercase is not a method that you can use on numbers but because we have time to say any while anything goes so it's not going to give us a warning but we should get a warning so we don't really want to have anyes in our code base so we could do something like this we type it as string and to make sure this function does what it says it does we could say that it returns an array with strings in there right so now this will work with strings and I can do two uppercase this would all be safe now let me just remove this so this is one example of how you could type it but of course it only works with strings now but we also want to be able to pass a number and other types as well like booleans and other types so how can we make this a little bit more General well we have generics so this value instead of hardcoding string we can say this is going to be some type and what do we return here well it's the same type right so whatever this is it's going to be an array of that with generics we are basically specifying a relationship the input is going to be of the same type as what you get in the array as the output instead of hard coding string or Boolean we make it more General with generics and we specify a relationship here in this case between a parameter and the return value we got red Squigly lines here because we need to specify it before this list of parameters that we want to have this T this is also called a type parameter so we need to use these angled brackets in front of the parameter list and then we can specify that this is going to be the T usually you want to use T you can also use K for these instead of T you can use K but the convention is to use T and when you do it like this with an arrow function you need to pass a comma here and this looks very ugly but this is necessary because we're working in TSX this will essentially be compiled to jsx and jsx when you write it like this it thinks you're creating a react element like div right with these angled brackets here we need to add a comma which makes it look ugly but this is to specify hey this function here has a type parameter we call that t and then we use it like this because of this ugly syntax I prefer to use a traditional function if you're going to use a type par parameter so let me quickly convert this I will comment this out we're going to specify a relationship between the parameter here and the return value so whatever we pass in this value can be a string and then we should get an array of strings if we pass in a number T is going to be number and we should get back an array of numbers if we pass in a Boolean T is going to be a Boolean and we should get back an array of booleans here we need to specify that this function is using a type parameter you do that in front of the parameter list so here you can just write T here you don't need to use a comma so I think this looks a bit cleaner so so let me remove this and now you can see I can call this with any type I want so what's an example of generics in react components well maybe this button accept some kind of count value but then also a history of those count values so count history let's say so now we need to type this and let's put that in its own type I like to call it button props so we have button props and then we have count value now we could hard code this as a number but maybe it can also be a string right maybe we want to pass like the string file but let's hardcode this as a number for now now and then what we want to get is a history of those values as well so that's just going to be an array with those numbers now what we can do is we can pass a count value it's going to be a number let's say five but then we should also pass a history of that and then we have an array this could be some some numbers here and this works right everything is a number now and everything works however what if we also want to allow to pass other types like a string right maybe we also want to allow the string five but if we pass the string five it should be an array of strings we have a relationship between these two props before we had a relationship between a parameter and a return value now we essentially have a relationship between two parameters what people call generics is actually just a type parameter so instead of hardcoding number here we want to make it more General we can say it's not just going to be a number could also be a string and maybe other types but whatever the type may be it should be the same type as the type in the array for count history so now we have specified this relationship between these two props and just like before you need to specify that this function will use a type parameter you do that before the list of parameters so here you can just use T and now because we have extracted this into a separate type we also need to pass it from here to here so we need to add another set of angled brackets here where we also say t then this type should accept a type parameter so then here as well we need to specify that this type is expecting a type parameter right so now we need to pass two additional sets of angled brackets to make this work because we have extracted this into its own type if we would just do it in line and just replace it like this that's not necessary right but here it is the important thing here and this looks the syntax here is always quite confusing you just have to remember with these generics is we have just specified a relationship between these two which means that this count value should be of the same type as what you see in the array for count history so if I do this now and now we try to pass in a string here the string number five I immediately get a warning from typescript which is it's saying I'm using a number here but it should be a string right because they always need to be the same type now so if I make these strings if I now make these strings you can see the errors disappear if I make the count value through a Boolean you can see we get a warning again these all need to be booleans now right so you can see whatever the type is of the count value that should be the same type as in the array now we have codified a relationship between these two props by using generics that's probably the most difficult Concept in typescript so it's okay if you don't fully understand that right now it's also not quite common that you have to do this Yourself by the way especially not as a react developer let me clean this up so we've seen the most difficult things there are a couple of other things that you really need to know as well so let me clean up here so before we were using some kind of color type right so we had red blue green now colors they belong to a theme and it's possible that other components also need to get access to this type and because other components may also need to be styled in a similar manner as the button so we need to re use this type we need to use it outside this file as well so we want to put it somewhere else we don't want to put it in the button component file so typically we want to create a lip folder Library folder in here you may be tempted to do something like index. d. TS to put the type in there cuz maybe you've seen that somewhere and this is not what you want to do these are treated as special files as declaration files and it's mostly helpful for typing thirdparty libraries that don't come with their own types so you don't want to use that do d instead you can just create a typescript file so we can call that types. TS and then we can just put that color type away from here and we can put it here and we can just export that just right export in front of it and then you can import it here so I can import the color from that types file right so now I'm importing a type and I can use that now so if I have my button props again I can just use that right so I could have other things of course children or font size but now I can also use this color type in other components very easily I can centralize all the reusable types in my app in a file called types. TS now when you import a type what you can also specify is that it's going to be a type because without it it kind of looks like a normal JavaScript variable that you importing here you can write type in front of it to make it extra clear that this is a typescript type there are some other benefits of doing that but those are very small I think the main benefit of doing this is that you just make it very clear and explicit that this is a typ type and that you shouldn't do anything with it like new color like treat it like a normal JavaScript variable you should only use it as a type so you will see that sometimes what you also need to know let me remove this is the unknown type so if you have use effect again you're fetching data let's say you want to do that in use effect let's say we're fetching data right maybe you're fetching some to-do we get a response we're going to parse that as Json and then finally here we get the actual data so the data that you get back from an API when a here by default typescript types this as any and as we've seen before we don't want to have any's in our code base at least not when we can do something about it the problem is here that we don't really know what we're getting back here we may have some idea of what we're getting back but we don't know for sure you know there could also be an error on the server here we may be using the wrong URL whatever the case you can never really trust what you're getting from some external API and so we don't really want to type this as any because it can cause a lot of bugs the more appropriate type here is actually called a Known Unknown means we don't know anything about it so you cannot just start using it and so here before we actually start doing things like data name. two uppercase and so before we can actually start using these methods we need to verify that what we get back here is actually the shape that we expect so when I hover here data is going if we're going to get an issue here typ Will Tell Us type of unknown so you cannot just use this so This is actually where schemas come into place so maybe you've heard of Zod and other schema validators so what you want to do here is you want to run it through SS where you basically do something like this you have some schema and you're going to parse you can use the parse method on there you pass in the data and it will tell you whether that data is indeed that particular shape once you've done that you can just use it as before do something with the data so if you can try replacing those NES with the unknown type and try to use a schema validator like Z to make sure it's it's of the particular shape that you expect it to be it's outside the scope of this video would be a bit too much but check out my other videos now if you don't want to manually do this typing from any to unknown yourself you may want to use this TS reset package from met pook with this package it will make sure that whenever you fetch data the data will automatically be of that unknown type and it has some other benefits as well it's also outside the scope of this video to to install all of that so make sure you check out my other videos or my course on react and nextjs in which we will also talk about typescript and also all these little details some other things that you really need to know are the following let me clean this let me close this so previously we were actually using a type from react we did something like children children and then react. react node so this is the react namespace but this is a type that we get from react we also used one for style so we had something like react CSS properties these are helpful because then we don't have to create this type ourselves we can just use something from react so where are these types coming from well if you go into the node modules you will see something called at types and this is where a lot of your thirdparty library types will come from so here we also have react here react da and also node for nodejs so that at types is a repository for highquality typescript type definitions it's also called definitely typed and it's basically just a big collection of types for thirdparty libraries because when Microsoft came out with typescript a lot of those libraries weren't using typescript yet so that was a bit of a problem to start using typescript so with this project a lot of the most popular third party libraries like react and other ones as well get some types from here right so that's where this is coming from now when you're using a framework like nextjs usually you're going to have some other typescript files here as well for configuration so typically the file that you're always going to have is a TS config file and here you basically decide the settings for typescript so typescript is going to compile your TSX file into a jsx file and you can determine how exactly that should go with with this jsx option that's not really interesting and nextjs by default it's set to preserve but you don't really need to use that the only other option here that you may want to use is this strict option I'm using a nextjs project here and in nextjs um it's set to True by default so what that means is that your time script is going to be strict so as a quick example if you remember we looked at when you have a state that's going to be null initially so for example some user State and this user can just be an object with name and email but initially it's going to be no because maybe we're fetching the user now when it's set to strict if you try to use that user variable for example to get the name we're going to get red quickly line here because it could possibly be null however if you set this to false I set this to false you can see the red quickly line disappears so it's less strict however I think it's better that you actually try to be strict with yourself and really make sure that when you try to access some property or method that is not null so just add this or you can just do it like this typically people use the optional chaining method and this strict setting doesn't only affect this it also affects some other things in general though you do want to be strict but typically your framework will already have set all of these settings for you so you don't really need to change anything here now in nextjs specifically we also have this next env. D.S file and this references the types for nextjs so if we're using some nextjs specific feature we also want to get correct typing and this make sure of that so as a quick example if you're f ing data you can do that in a server component these days we can fetch data to some URL and what you can do in nextjs nextjs has extended this so you can actually write next here and this is actually an object and then here what can I pass I can do control space bar and I get some intelligence here it's telling me I can pass revalidate and text if I try to pass something here that's a string I get a warning here because it should be a number this is a nextjs specific feature they have basically altered the fetch API a little bit to do some additional things and as you saw we got intelligence and we get that typing because we are including this file as well which is referencing where those types for nextjs are so there was a lot to take in it's completely normal if you're a little bit confused right now now I have a complete react and nextjs course in which we also talk a lot about timecrimson in any case thanks for watching and I hope to see you in the next one bye
Info
Channel: ByteGrad
Views: 101,877
Rating: undefined out of 5
Keywords: typescript in react, react typescript, ts react, typescript, typescript react tutorial, typescript tutorial, ts tutorial
Id: TPACABQTHvM
Channel Id: undefined
Length: 53min 21sec (3201 seconds)
Published: Mon Sep 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.