Learn TypeScript - Full Course for Beginners
Skills:
AI Pair Programming70%
Key Takeaways
This video course introduces beginners to TypeScript, covering its basics, defensive coding, custom types, and utility types, with hands-on examples using a pizza app.
Full Transcript
learn the basic building blocks of typescript while discovering firsthand how typescript can make your life easier and your code less air prone popular instructor Bob zeroll teaches this course typescript is a superet of JavaScript meaning all valid JavaScript code is also valid in typescript however typescript enhances your coding experience by enabling you to write code with greater confidence in the stability and longevity of your projects hi there and welcome to this introductory course on typescript my name is Bob Zol and I'll be your teacher through this course guiding you through learning one of the most important things you can learn as a front-end web developer now there might be a lot of reasons why you're here in this course trying to learn typescript but I'm going to give you three of the most important reasons you can learn typescript the headliner reason for learning typescript that I would offer is the confidence that it gives you as a developer typescripts ability to check your code during compile time or using modern idees essentially in real time as you're typing your code dramatically reduces the number of app crashing runtime errors that would normally only be caught after your app is running and possibly even deployed live to production because typescript can catch a lot of those errors before anything gets pushed up live your confidence as a developer in the stability of your code will be through the roof another reason I would offer it's important to learn typescript is the added productivity that it brings to you as the developer sure typescript does take a bit more time to write than just slinging regular JavaScript code around but there are a number of really neat features that make your life as a developer a lot easier by simply using typescript in your project in vs code for example yes in JavaScript you'll get some autocomplete but you'll see as you're using typescript autocomplete turns up to a completely different level in modern typescript enabled idees there's also refactoring capabilities immediate error checking as we talked about in point number one and a bunch of other things that you'll find as you're using typescript that just greatly improve your developer experience and thus your productivity and a third reason I would offer that it's really helpful to learn typescript is that it will improve your employability assuming you are a junior or maybe even a mid-level developer that is on the job market or will be on the job market in the future learning typescript is oftentimes considered table Stakes by many companies even if it's not explicitly listed in their job description as such knowing even a little bit of typescript can really set you apart from other Junior developer candidates so what exactly will we be covering in this course well this is an introductory course and by the end of the course you will have an understanding of the fundamentals of typescript and we'll be talking quite a bit about why typescript is so useful as far as the topics goes we're going to cover the basic literal and custom types we'll talk briefly about optional properties unions type narrowing some built-in utility types that exist already in typescript and generics which essentially allow you to create your own utility types or to make your functions and other types more flexible by understanding these fundamentals of typescript I truly believe that typescript can be a catalyst that helps train your brain to think like a senior developer as such there's one thing in particular that I remember when I first started learning typescript and that is that it can be challenging to learn at first you have nothing to worry about because you're here on scrimba you're going to be getting your hands on the keyboard quite a bit throughout this course practicing really understanding what you're learning and I've tried my best to really break down the topics into bite-sized chunks that are really easy to comprehend still one of the challenges I have heard from a number of people who are learning typescript for the first time is that it feels like we're just adding a bunch of extra work without any additional benefit especially if you're trying to convert an existing codebase into typescript it can be quite overwhelming to see all of the errors pop up when you change your file to a typescript file however as my friend keny dods puts it typescript is not going to be making your life terrible it's simply going to be showing you how terrible your life already is it's really important to remember that the errors that you see show up in typescript they're not there to bug you or be annoying they're really there to protect you against some of the Loosey Goosey typing that happens in vanilla JavaScript an analogy that I thought of that kind of helps me understand this better is the concept of building a blueprint or a sketch of a project before you actually start building it on a large scale if you can imagine someone trying to just walk up to a pile of lumber and start building a house without a plan you can tell that that's probably not going to end very well yes drawing out a blueprint planning ahead it takes a lot of additional work Beyond just building your house but the benefits are obvious and I believe after you've been exposed to typescript and you've built some projects using typescript you'll probably see it in a very similar way maybe to get a little bit more specific let me talk about what this item is right here this is called a stud guard and it's an example of planning ahead of time to avoid catastrophic issues in the future now the idea of a stud guard is often times homeowners will try to find a stud and nail or screw something into that stud maybe to install some kind of Hardware or hang something heavy or whatever it might be however in certain parts of our house it's really important that we don't nail through the stud if I had a screw that was too long and right here tried to screw into this section I would hit this waterline or even worse it could be electrical line or even worse could be a gas line and so these stud guards which are made of 16 gauge steel make it so that it would be really difficult to get through this section of the stud and accidentally cause something terrible to happen a little bit of extra work planning ahead just like using typescript can save you big headaches in the future Now typescript does not solve every programming problem like this meme might suggest the main focus of typescript is on fixing possible runtime errors more spefic specifically anything that would be a type error and as I'm sure you've experienced not every error in your code is a runtime type error typescript can do quite a bit to protect you against the most common errors that people write into their JavaScript code but it won't protect you against certain things like logical errors that said we're about to see firsthand just how many errors we can fix by simply changing a file from a JavaScript extension to a typescript extension I'm really excited to jump into this code my name is Bob zero as I mentioned I'm most active these days on X you can click my username here to go directly to my profile I'd appreciate a follow so without further Ado let's jump right into learning typescript when I first started learning about typescript a number of years ago I really struggled with understanding what benefit I was actually going to get by using typescript instead of vanilla JavaScript writing your code in typescript does require a relatively significant overhead in terms of extra lines of code that you have to write and considerations that you have to take and so for this course I really wanted to demonstrate the improvements that your code will receive by using typescript instead of JavaScript just by itself so the approach I'm going to take might be a little bit different but stick with me it's going to be fun and I really think it's going to highlight the benefits that you'll get out of using typescript the way I'm going to approach this is by building a really simple restaurant app it's just going to be console based so we won't be worrying about HTML or anything like that and we're going to start by writing wrting it in regular JavaScript and I'm going to give you a couple really simple challenges but again stick with me this is going to be really fun okay so we're going to create a pizza restaurant and the first thing I want to do is create a menu it'll be an array of items each of those items will have a name and let's go ahead and add a couple pizzas here we'll say a margarita pizza margarita and we'll give it a price and let's go ahead and add four different pizzas and for the sake of time I'll speed through adding different pizzas to our menu all right in our pizza restaurant we also are going to want to keep track of the cash in the register let's say we start each day with $100 and we'll also want to keep track of all of our pizzas in the queue as people are placing orders for pizzas this way the workers in the kitchen can know what needs to happen next so let's say we have an order que and we'll just initialize that as an empty array okay let's do a quick series of challenges this is mostly just going to be a way to get your brain and your fingers working right away so let me type out your first challenge okay this is about as simple as it'll get your challenge is to add a little utility helper function for us that's called add new pizza it should take a pizza object that's just like the shape of this object up here in our menu and it's going to just add that object to the menu pause now and work on this challenge okay let's add a function called add new pizza it's going to take a pizza object and simply enough it's going to do menu. push the pizza object Perfect all right we're really on a roll here let's get rid of this challenge text and already it's time for another challenge okay this one's a little more involved but still very doable your task is to write another utility function we'll call it place order that takes a pizza name so pepperoni for example as a string and first finds that pizza object in the menu so this whole object then it adds the new price that you just generated as a business to your cash in the register then it should create a new order object which is going to be just like this one that you see here it'll have a pizza property whose value is the object that you got from step one and then a status which we will set to the string ordered and then it will push this order object to the order Q array and then just for good measure we'll go ahead and return that New Order object object just in case we need it in the future okay pause now and work on this challenge all right let's do it we'll have a function that's called place order it's going to take a pizza name as a string there's a few different ways that you could do this but I'm going to grab the selected pizza and that's going to be the returned result from calling menu doind doind is an array method menu is an array of course and find is a method on all arrays where you provide a callback function find will iterate over all of the items in your array in this case we'll call it a pizza object and from this callback function that I get to write if I return true at some point then find will return the object that it found and that's what I'm saving as selected pizza so in this case I'm looking for the pizza in my array with the pizza name that was passed in here so with pizza object I'll say if Pizza object. name is equal to Pizza name the parameter passed into this function then it will return true and I have correctly found my pizza okay then we'll go ahead and increment our cache and register so we'll say that plus equals the selected pizza. price okay and that does it for steps one and two then we're going to create a new order and this will be an object that has a pizza property that's going to be our selected Pizza object and a status which we will default to ordered then we will push into our order Q so we'll say order q. push our new order and return the uh let's new order here okay one more quick challenge and then I promise we're going to get to the point okay in this challenge we have one more utility function to write we'll call it complete order it's going to take an order ID which will be a string as a parameter it will look in our order Q array for the order with that ID and then simply Mark its status as completed instead of ordered and then for good measure just like we did with place order we'll return the found order from the order queue as a note you'll need to make sure that you're adding an ID to the orders whenever you create new orders right here we're not including IDs so that's an improvement or a modification that you'll have to also make to the place order function and since we're not using a real database here you'll just create a global variable called Next order ID that you can start at one let's say and increment every time a new order is placed all right pause now and work on this challenge right let's create a function called complete order this is going to take an order ID and then before we get too far down that rabbit hole we'll go ahead and create a new variable we'll call it next uh order ID and I'll set it equal to one to start here when I'm creating my new order I'll go ahead and add an ID property and I'm going to use this trick where I can say next order ID Plus+ this will return the original next order ID before it gets incremented that's the value that will be set to the ID here and then once it's done doing that it will increment it so that in the future when I do this again it will have already changed from 1 to two and it will then increment it from 2 to 3 for the next time that it gets used by the way for anybody that's shouting at your screen and was probably shouting at your screen when I was doing this line L of code as well I know that there's bugs in here we're going to talk more about that very soon so don't worry about me I know that there's problems to fix down in our complete order function we can do the find method that we used before so let's go ahead and say this is our order we're going to use order q. find we'll say for each order that we're looking at we're looking that the ID is equal to the order ID that was passed into this function we will then change the ORD status to completed and return the order now I do want you to use your imagination a little bit here of course we're talking about creating a console-based pizza restaurant which is of course delicious but also a bit contrived as it stands but imagine that you've spent the last 30 or 60 Minutes or maybe even a full day or two working on some new feature for the app that you're currently building and you now feel like you're ready to start testing things out so let's go ahead and let me clear up this challenge text and we'll just test a few things out we'll add a couple new pizzas and let's add one of my personal favorites this is going to be a chicken bacon ranch and we'll say that the cost is $112 we'll add another pizza and let's call it a maybe a barbecue chicken that'll also be 12 and then maybe let's add something a little spicy in here we'll call it a spicy sausage pizza and maybe this one's $11 okay and then we will place an order and this will be for a chicken bacon ranch and we know I Hadad of time that our first order ID is going to be starting with a one so we'll go ahead and test our complete order and we'll test the order with the ID of one and then in true fashion let's go ahead and console log everything that we have so we'll console log our menu just to see if our add new pizza is working we'll console log our cache in the cach in register and let's check out our order Q all right now if you've actually been following along You' know that this code is pretty full of some minor bugs when you wrote the challenges you may or may not have introduced similar bugs but at a glance if you were to run through this program just reading through the code I don't think it's that much of a stretch to think well this looks pretty good yeah let's push this up to production we'll run a couple tests and see if it works and then push everything up if you took the chance to pause and run this code you'll know that we're going to be running into all kinds of little problems first of all we have this type error assignment to a constant variable well a type error this is actually something that would crash our program if somehow this made it past testing or didn't involve any kind of manual testing it would have gotten pushed to production and our app would have crashed there's also a bug in the way that I'm testing my complete order of course I used a string this is again a bit on the nose because we know that this should be a number but this would have probably crashed our program as well now before taking a bunch of time and fixing these errors this is the perfect opportunity for us to move this project over to typescript and first of all see what errors typescript script is able to pick up without us making any other changes to the code and then to dive deeper into typescript and see how we can augment our code so we can teach typescript how things are supposed to look so that it can catch other bugs that it otherwise wouldn't be able to so before this bug Laden code gives me any more anxiety let's move over to typescript and see how we can fix everything okay let's shift things over and start using typescript for this project and see what typescript is is going to be able to offer us immediately out of the box in scrimba the way typescript is running under the hood is a little bit different than if you were following Along on your local machine normally I would be able to just change my Javascript file to a TS file extension and set typescript up as a dependency of my app but with typescript running in the background on scrimba I need to make sure that I actually create a brand new file called index.ts we'll talk a little bit more about setting up typescript in a local environment so this isn't a big deal that we have to worry too much about now but another scrimba specific thing I need to change this tots and we'll go ahead and copy all of our code over from JS to TS and look at that we get a bunch of red squigglies of course JavaScript was perfectly happy to let us write the code that we had before but out of the box typescript is able to warn us ahead of time of any potential errors that we might have now I want to reiterate that throughout this course anytime you see these red squigglies I want you to actively move your Mouse hover over the word that has the red squiggly and see the intellisense popup that shows up I can see it on my end but it's not something that scrio records into the scrim so very often I'll be saying if you hover your mouse over this item and look at the popup I actually want you to do that in fact I want you to do that pause now start hovering over some of the red squiggly words that you see here see if there's any bugs that you can fix right off the bat well some of these are giving us errors about the variable implicitly having an any type that's something we're going to talk about in the future but if you came down here to cach and register you can see that it says you cannot assign to cach and register because it is a constant or a readon property and assuming at this point you know the difference between a const and a let that should be a pretty obvious fix maybe out of habit I initialized this as a const but I'm trying to assign a new value to it in the future and I can't do that with a const so let's go ahead and change this to a let and by making that very simple change typescript is now satisfied when it comes to this cach and register variable let's come here to next order ID and we have the exact same problem this needs to be a let instead of a const by doing that now typescript is satisfied about next order ID at first glance using typescript can be a bit intimidating because of all of these red squigglies that show up and because of the additional code that you will have to write to fix the errors that it's warning you about but I think a better better approach or a better lens to look at this through is that typescript is showing us the problems in our code nothing about using typescript here is introducing new bugs it's just showing me where the bugs already existed this means I can find them immediately as I'm typing my code instead of having to wait till it crashes for our users so over the next few scrims we're going to fix the bugs that are already here we'll be adding new features to our app and seeing where typescript is and isn't happy all while using that to drive forward our knowledge of typ script there's one more era in here that we're able to fix before we even start writing typescript specific code and that's here on line 18 go ahead and hover your mouse over selected pizza here and you'll see the popup says the object is possibly undefined this is a great example of a time where typescript is able to warn us ahead of time that we have a potential problem and this brings me to a point that I will likely reiterate in the future in this course and that's the difference between coding on the happy path and the sad path now the happy path is when we are writing our code and we just assume that everything is going to work out perfectly this does tend to be the code that people who are new to coding will write I would say mostly because they haven't been hurt in the past by code push to production that didn't account for the edge cases that can pop up when you run code in production and that's because this is the easiest code to write we have a task that we're trying to solve we write the code that solves that task and then the temp ation sometimes is just to move on however typescript forces us to take a step back and consider the sad path the sad path is when we account for or assume that problems may occur it forces us to think of those edge cases where problems can arise and address them in our code the first time before we have complaints from our users in the live production version of our code telling us that the code is crashing their browsers in a way you can think of this as being a more defensive way to write your code and truly it's not asy easy you really have to think about all of the edge cases that can occur when your code is running in a live environment and it can be difficult to imagine the sometimes weird ways that our users might use our code in unexpected ways now typescript is not perfect for this but it makes writing for the sad path significantly easier and a perfect example here is with selected Pizza when it tells us that this object is possibly undefined and I'm sure that you've run into the error that happens when you try to access a property of undefined you'll see something like cannot access property price of undefined what's happening and what typescript can foresee being a potential issue is that we're trying to find an item in our menu array based on the pizza name String and typescript can see that it's possible this may come back as undefined if we're searching for a pizza that maybe we misspell or is some nonsense Pizza that doesn't exist inside of our menu then selected Pizza is going to be undefined and typescript says that would crash your program to satisfy typescript script in this case we can code a bit more defensively and say if there is no selected pizza then first let's go ahead and run a console. error we'll maybe say something simple like the current Pizza name that you're trying to search for does not exist in the menu then to satisfy typescript we need to return from this function or alternatively we could throw an error but the point is we want to stop execution of this function and by adding this return in here now typescript knows that this L of code will never get reached if selected Pizza is some falsy value like undefined I guess I could be a little bit more specific and say something like if selected Pizza is equal to undefined notice that that also satisfies typescript in this case I'll go ahead and just leave it as a check for the falsy value okay now it does feel a bit ridiculous that we haven't actually run our code yet the reason is because I knew there was a bunch of errors in here that we had to start fixing but now it's time for us to finally run our code and we can see that we do get a type error that says cannot set properties of undefined I thought this is what we just fixed this one though is talking about setting the status property now where is that happening that is happening where we complete the order order. status now there's a few points to be made here first of all it might seems strange that typescript is not warning us that order is potentially undefined in the same way that it was warning us that with selected Pizza there actually is a reason for this we're going to address it a little bit later on but secondly and I'm sure this was dri a bunch of people crazy when I'm calling complete order I'm passing in a string ID instead of a number ID and typescript isn't warning me about this at this point in this particular program we've reached the limit where typescript is able to help us without us going out of our way to write typescript specific code it's really nice that we able to fix a couple bugs and we can see that there are potential other bugs simply by including typescript in our project and using a TS extension on our file instead but since we've reached that limit where typt SCP is no longer willing to help us without defining specific types in our program let's finally jump in and start learning some typescript specific code starting from the basics we're starting to see some of the benefits of using typescript but I think they will really start to sink in as we're building a real project in order for us to do that we have to learn some of the very basics of typescript and that is how to type a variable when I'm writing vanilla JavaScript I can say something like let my name equal Bob and because typescript is a superet of JavaScript any JavaScript code that we have will be legitimate typescript code now perhaps unconventionally I'm going to start this lesson by saying when you write a line of code like this typescript is very smart and it's able to infer what data type is being used for the variable that you just created so go ahead and hover your mouse over this variable my name let it sit there for just a second and you'll see a really small pop up that says Let My Name colon string here what typescript has done is it has inferred or derived what data type my name is supposed to be now while we are about to learn how we can manually provide different data types to our variables I do think it's important to note that the work that we're about to do is busy work it's not something that typescript requires you to do because it's able to figure out the data types simply by the data type that you assign to it to demonstrate that if I then try to say my name equals a number we get a red squiggly and if you hover your mouse over my name we'll see that it says the type of five is not assignable to the type of string in other words typescript is angry that we're trying to reassign a number value to a variable that was originally set to be a string as a side note sometimes people talk about javascript's Dynamic typing nature where in regular JavaScript this operation is not a problem at all they talk about it being a strength in the flexibility JavaScript but in practice in the real world off the top of my head I can't think of a reason why this would be a beneficial feature for us to be able to reassign a string value to something that's a completely different data type it's a code smell to me which means that if I see something like this or I'm attempting to do this in my code then I'm probably structuring my code in a bad way so typescript forces us to think of better ways to organize our code anyway let's get back to manual typing now although typescript has correctly derived that this is going to be a string type I can manually give a type by typing a colon immediately after my variable name and then typing out the lowercase version of what data type I want this to be so this might look a little strange this is one of those instances where the typescript syntax is different from JavaScript syntax this would not be correct syntax in vanilla JavaScript but it is something that you'll see all throughout typescript and you'll just get used to typing it now let's get our hands on the keyboard and do an admittedly really simple challenge we've already used the Primitive dat data type of string lowercase s string and in typescript the other two primitive data types that we'll use are number lowercase n and bullion with a lowercase b the reason I'm creating a distinction between the uppercase and lowercase is because in JavaScript there is an uppercase s string Constructor and uppercase n number Constructor and the same with Boolean but that's not what we're accessing when we're doing these types okay should be super easy pause now and work on the challenge of explicitly typing these variables below well if we hover over number of Wheels again we can see that typescript derived the data type of number I guess this could be an easy way to cheat into knowing exactly what to be there but this is so straightforward I'm not concerned about that we're going to add colon number and colon Boolean in order to explicitly type these variables okay there's a little bit more syntax that we're going to learn when it comes to manually providing some types so once you feel feel pretty good about what we've done here let's keep moving forward we'll be talking about typing inside of functions really soon but I thought it would be a good chance to apply what we've learned to our pizza restaurant app so your challenge is to teach typescript what data type should be used for the order ID parameter here in our complete order function then once you've added that keep a close eye on the rest of the program to see if typescript has any new warnings and if something pops up go ahead and fix that pause now and work on this challenge again this is a bit on the nose because we know that this is not supposed to be a string but let's just assume that we missed that little error and we'll say that this order ID is supposed to be of a number type and sure enough because we've gone out of our way to add just a few additional characters to our complete order function typescript now knows that we're using this function incorrectly we're passing in a string where it shouldn't be if you cover your mouse over the one it says that the argument of type string one is not assignable to a parameter of type number and great yes that should be a number let's go ahead and make that a number and let's hit save and look at that there are other potential issues in our program but because we're using typescript we are no longer crashing with type errors all right now at this point our app would benefit from us starting to write what's called custom types so that's what we'll start learning in the next lesson we've talked about a few primitive types like string number and Boolean but in typescript we also can create our own custom types at first this isn't going to seem super useful but just bear with me we can create new types by using the type keyword this is something that exists only in typescript and by convention the name that we give our type is going to start with a capital letter for example I could say type food is equal to string by doing this I now could use the capital F food as my way of providing a new type to this favorite food variable now doing this with primitive types like strings numbers and booleans won't make a whole lot of sense until we talk later down the road about something called unions or intersections but this can come in handy for creating custom types around objects let me show you what I mean I have this person object with three properties name age and is student a pretty common thing with objects is that you might have multiple of the same kind of object so let's say we have a person two which looks very similar we're going to have Jill age know 66 and we'll go ahead and say is student is false as it stands there's no problem with this code however you might have noticed that I used a lowercase in this is student property and an uppercase s in this one one of the benefits of using typescript is that it forces us to stay consistent and although this may not cause a bug the way it's written currently it seems pretty ripe for a bug down the road what we can do is create a custom type of an object that defines the shape of the object where we can give it exactly what the property names are I can create my custom type by using the type keyword I'll use capital P person as my type and I'll set it equal to an object and what I'm doing inside of this object type is telling it what properties it will have like name but then instead of providing a value I'm going to give it a type I want my name to be a string type one quick side note about custom object types in a regular JavaScript object it's syntactically correct to have a comma to separate each one of your property names however when you're creating an object type like this you can use commas you also can use semicolons you also can just leave them out so for me personally I'm probably going to just leave out anything at the end here but you can choose whatever you want and it's most important just to stay consistent within the project that you're working in okay just so we can avoid some passive list listening here I'm going to include a really simple challenge here I know it's a little bit of busy work but getting your hands on the keyboard is always a win when you're learning to code so your challenge is to finish the object type definition so let's say so that it looks like person and you know what let's call this person one so that this type is the same shape as person one pause now and work on the challenge okay well we're going to put age is a number and is student is a Boolean simple enough now let's take a step back obviously writing this out has cost us more work it's used up five more lines of code frankly it doesn't take very long but it can feel like it's breaking your flow however by doing this we've added an extra degree of type safety when I'm defining person one I can use my colon and set it equal to my custom type person and I can do the same thing for person 2 we'll say this is capital P person and check it out even though we had to go out of our way to define this custom object type by doing that little extra work we have already been able to identify a potential problem we know that these two objects should be the same but we might have just missed it because we're fallible humans let's put in a capital S and satisfy typescript spend some time playing with this code and when you're ready we'll move on and talk really briefly about nested object types let's set a standard in our pizza restaurant app as to the shape our pizza objects should have and I'll have you do that through a challenge your task is to create a pizza object type it should include a name and a price property and that'll be the extent of the challenge for now we'll apply that in just a minute so pause now and work on this challenge okay this should be pretty straightforward we'll say we have a new object type called pizza and it needs to have a string name and a price which is a number okay easy easy enough now what I want you to do is to pause look through our code and see if there's anything obvious that you can enhance with typescript by telling it that the type should be of this pizza object type so pause now peruse through the code experiment a little bit see what happens and then I'll have an official challenge for you well if you're anything like me you probably went through and started looking at the different red squigglies that we have and right here in our add new pizza we have this pizza object which if you hover over it typescript warns us that it implicitly has an any type that term any type isn't necessarily supposed to make any sense to you yet so don't worry about that we will be covering that soon but this brings us to the next challenge all right your challenge is to teach typescript that this pizza object in this add new pizza function is supposed to be of type pizza then like before once you've done that look through the code and see if there are any new warnings you need to deal with of course there are going to be and fix those issues pause now and work on this challenge all we have to do is put a colon and then a capital P Pizza after this typescript is no longer warning us that pizza object is implicitly in any type and in fact if you hover your mouse over Pizza object here it will specifically tell you it's a parameter and it's of type capital P Pizza all right let me clean up this text and we'll just go ahead and peruse down here in our code and check it out down here when we were adding a new pizza we have these three new errors over cost if you didn't have a chance to do this already have your mouse over cost and you'll see that it tells you that the argument of type Nam string cost number is not assignable to the parameter of type Pizza okay well that's interesting the next thing it says is that the object literal may only specify known properties and cost does not exist in type pizza and sure enough when we wrote this we might have forgotten that it actually is supposed to be price not cost typescript saving us again you can go ahead and change these to price instead of cost and hit save and sure enough everything is working as we'd expect now I assume a number of you were probably screaming at me this whole time when I first wrote cost here in the beginning I promise it was all planned out and staged but notice that without writing our pizza type and specifically telling add new pizza is supposed to be taking a pizza object that our program wasn't necessarily crashing if you looked at our menu before we had an array of the items that we initialized in the beginning but then we also had added items with a name and a cost property and I don't know about you but that makes me feel gross to know that we have these mixed types in our menu that's just asking for crashing bugs down the road by adding just a few lines of really simple typescript we were able to defend against that problem that not only would never have shown up in regular JavaScript but also wasn't even showing up as issues here in typescript until we went out of our way to create this pizza type okay we're making good progress on fixing up the bugs in this app before we move forward there's one really easy update that we can make and it's so easy I'm not even going to make it a challenge here in our place order function if we hover over Pizza name which typescript is warning us about it says that it implicitly has an any type let's go ahead and type that as a string and get rid of that warning great well it looks like the majority of the issues actually all of the issues that we have left have to do with this variable order CU so let's go ahead and Tackle this issue next let's say we want to build out our person object a little bit more and we want to include an address property well typically something like an address wouldn't simply be represented by a string but instead by a nested object the most straightforward way to do this is to Simply type it out as if I were typing out a regular object I can put my curly braces there and just like I did with the rest of my type I can say maybe there's a street portion of my address and this is going to be a string we'll just stick to Street city which is a string and then we'll also say uh let's do country and that'll also be a string okay what do you notice about our code now well our objects below are typed as person objects or person types but we just changed the definition for person to say that it must include an address if we hover over the red squiggly which you should also do right now as you're watching this it tells us that the type of this person one with the object as it currently stands is not assignable to the type of person in other words there's a mismatch between the derived type of this variable that we've just set which typescript can see is a name with a string and age with the number and a is student with a Boolean and it sees that that doesn't accurately match the person type that we just redefined with the address property assuming we do actually want every one of our objects to have an address property we would need to make sure that we update our objects to include an address property that includes all of the subproperties of the person type definition under address so that means I would have to have a street let's just put something generic in here a city we'll say this is any town and the country we'll say is USA I'm sure you noticed as soon as I added country to my address it then satisfied the definition for this person type and typescript stopped complaining removing any one of these properties is going to make typescript complain because it doesn't perfectly match the type that was up there now I can guess what some of you might be thinking at this point because this is exactly what I thought at this point in my learning of typescript is that typescript feels so extremely rigid we've become very accustomed to writing JavaScript where essentially anything goes and we fix the bugs that we have while we're testing out our app and we kind of hope that we fix it all but at least we get some freedom and flexibility I have two things to say to that first of all we are going to learn a way in which we can make these properties optional so that typescript won't scream at us if for example we don't want person one to have an address but secondly I would say that you should work really hard to force yourself to become comfortable with that extra rigidity that's offered by typescript at first you might think that it's sort of stealing the fun of slinging JavaScript code and building projects on the Fly really quickly however when you're working in a real production environment at a company you're going to find it less fun when you have to fix bugs in production because you didn't have the extra rigidity and type safety that comes by using typescript all right I'll get off my high horse now one last thing before we move on another common way that you will see this nested object structured is by not necessarily defining the types right here in line with our person object but instead simply creating a separate type for the address alone and so I'm going to turn this into a challenge your challenge is to try and figure out how to move the nested address object that we have here into its own type like we see here and once you've done this correctly there should be no red errors in the editor below I do want to point out that I haven't explicitly taught how to do this what I'm trying to accomplish here is getting your brain thinking get your hands on the keyboard and see if you can put two and two together to figure out exactly what this would look like if you're feeling stuck rather than just hitting play and moving forward I would recommend searching on Google or opening chat GPT and formulating your question specifically so that you can be engaging your mind and really going out of your way to try and learn these things when you just push forward and watch me do it it doesn't sink in quite the same way as when you are more engaged okay getting off my soap box now pause now and work on this challenge well I should be able to just take the properties of my address here I'll cut those out I'll put them into their own address type up here and then instead of doing an inline object here I can simply refer to the capital A address type that we defined above and after I've done that you can see there are no more errors in the editor either of the two ways that we just saw it is completely fine if you think that you are going to be using this address type elsewhere in your code as a standalone type then it makes sense to separate it into its own address type like we just did or if you already know that address is only ever going to exist as an object in the context of a person object then you can just leave it nested inside of the person object and that will work just fine as well once you've had enough time to play around with this and feel pretty comfortable with it then you'll be ready to move on to the next Grim where we will talk about how we can make some of these properties optional if we need to something that might put your mind at ease regarding typescript rigidity is knowing that when you're creating object types like we see here with person you can Define some of these properties to be optional now this comes with a caveat when you're making decisions about whether something should be optional typescript comes with a number of ways that you can relax that rigid nature but you should learn to force yourself to really ask the question do I really need this to be flexible we're going to see multiple different ways in which typescript offers that flexibility however they always come with the trade-off of reduced type safety let's get the syntax out of the way for doing this because it's really simple for example if don't necessarily want every person to have an address you can see removing address gives me some typescript warnings when I'm defining my type I can simply put a question mark after the property name that's going to be optional you can see as soon as I typed that question mark the warning under person one went away and that's because now the address property is optional this has offered me a bit of flexibility however as I mentioned it does reduce my type safety we'll be talking more about adding type safety to functions soon but let's say I have a function that's called display info and this function is going to take a person as a parameter and in it it's going to console log and let me use a template string here we'll say person. name lives at and then we'll stick in person. address. Street okay so now later in my code or maybe in another module I import display info and I'm going to call display info and pass person one to it well this is a bit on the nose I'm sure that you can see what this this problem is going to be let's hit save check our console and sure enough cannot read properties of undefined that dreaded error that we see notice that it says it's a type error this is an error that was introduced well really for two reasons one because we chose to make this an optional property but in truth maybe more importantly because we didn't add any type safety to our function I can technically get rid of this error by using optional chaining right here on address one thing to note is that currently scrimba doesn't understand optional chaining but trust me this is going to work just fine however this solution isn't great because if I hit save we see that we get Joe lives at undefined not a program crashing type error but still not a great experience now don't let me get in your head too much adding an optional property is a completely legitimate and fairly common thing to do in typescript I'm just making sure I do my due diligence and letting you know that every time you add one of these sort of flexibility enhancing features of typescript you are going to reduce your type safety by a little bit okay let's move on and apply what we've learned to our pizza restaurant app okay let's Jump Right In with the challenge your task is to create a new order type in that type it should have an ID pizza and Status properties I won't to explicitly give you what data type those should be but just look through the code if you need some hints as to what it will be pause now and work on the challenge okay let's let's create a new type called order and this will be an object it's going to have an ID which is going to be a number remember down here we have our order numbers that we're keeping track of and so that will be a number the pizza property is going to be a pizza type which makes sense because it's a nested object inside there and the status property for now is just going to be a string we're going to talk about this a little bit later let's clean up the challenge text and hopefully that was pretty straightforward now this wasn't explicitly part of the challenge there's a chance that you came to the order queue and decided to try and make this of type order and you'll notice that that doesn't fix the warning that typescript is giving us and that's because the order Q is an array it's not a single object so before we can fix this we need to learn about typing arrays it's fairly straightforward so we'll do that in a quick scrim after this and then we'll come back to our pizza restaurant and fix these issues we've learned about how to manually type the Primitive types in typescript for example if you have something like let age equal 100 you can manually tell typescript that age is going to be a number like this and there's a similar syntax when we are typing arrays so if I have an array and maybe we'll just call this ages so that it makes a little more sense maybe 100 and 101 notice that typescript is complaining about the type of Ages hover your mouse over the variable ages here and you'll see that it says the type type number square brackets is not assignable to type number well it kind of gives away the Syntax for typing arrays all we have to do is simply put a set of square brackets as if this were the array syntax with an empty array right after the type and this is how we teach typescript that ages should always be an array that consists only of number elements if we were to try and put another thing in here maybe the string one then we get an error again it tells us that there's a problem with this last element because it is not a number inside of this array the same will happen if I try to push something to the array that isn't of the correct data type like ages. push true red squiggly shows up here under true and it says that it's not assignable to the parameter of type number this should all be pretty straightforward for you at this point I think it's important to note that in the same way that typescript is able to infer a regular number typescript is also able to infer the data type of an array of numbers so when it's an array with some simple primitive data types in there we don't have to manually put colon number square brackets or string square brackets or anything like that we can just let typescript do its job and we're going to get the same benefits in the end however when we have a custom data type like a person data type that we've seen before let me fill this out again we have a name String we'll say an age is a number and is student is a Boolean when we want to create an array of these people objects well actually I think you'll be able to figure this one out let's make it a challenge okay I took away some of the busy work here for you by creating a couple of person objects I've already typed them as a type person and your challenge simply enough is to create an array with person one and person two in it and then to manually type this array as an array of person types pause now and work on the challenge okay let's go ahead and set this equal to an array we will will stick person one and person two in there and before I manually type this as an array of person types I'm going to hover over this variable people and you should do this as well and you'll notice the popup does correctly type this as a person array because every item in this array conforms to the person type it knows that this people array should continue to be an array of person type but that's not what the challenge says the challenge says to manually do it so we'll put colon person and then the array bracket syntax now normally as I've said it's good to let typescript do as much inference as it can especially when it comes to primitive types like numbers and booleans however I'm a little bit more torn here yes typescript is able to infer that people is an array of person types however adding it here explicitly does make it a little bit easier for myself or other developers to read in the future so in this case I'm just going to leave this here we also can note that if I don't manually type it and then I remove the person type declarations here and hover over let people we can see that now it has inferred the type to be an object literal with all of the properties instead of having the person type as an array here but we're using typescript I can't think of a good reason to not type these as person objects so we'll just leave it like that and maybe I'll go ahead and put back my colon person array as well really quickly there is another syntax which you may see floating around and we will talk a little bit more about it later in this course when we talk about about the concept of generics but for now it's enough to know that there is a syntax where you can use capital A array a set of angle brackets and then put your type inside of the angle brackets and I could use this in place of my person with square brackets just like this this is going to do the exact same thing you can hover over people and see that it is correctly knowing that it's an array of person types so I'm just covering my bases here don't worry too much about that we're going to stick with this syntax for now and talk more about that other syntax when we talk about generics okay let's get back to our pizza restaurant and apply what we've learned to our code over there here we are back in our pizza restaurant and your challenge is to fix the typescript warnings that we have throughout our code about order Q pause now and work on this challenge okay well we already have our order type that we wrote previously and we know that the order CU should should always be an array of order objects so by doing that typescript is no longer complaining about order q and if we come down we only have one more typescript warning here and this is awesome this is actually a really helpful warning but everything else has resolved itself now that typescript knows that order Q should be an array of orders it's able to ensure that we won't have any type errors in our program because we've generally written everything okay now there is this one new warning here under order. status order says that it's an object that is possibly undefined and this should look familiar this is exactly the warning we were getting above when we were writing selected pizza. price it was telling us that selected Pizza is possibly undefined so that brings us to the next challenge okay now your challenge is to fix this warning below by handling the sad path scenario notice I'm being a little bit vague here I do want this to be a chance for you to engage your brain try to remember what we've learned before look through the rest of the code that should help you out quite a bit pause now and work on this challenge when we're running order q. find if we provide an order ID that does not exist in the order Q then this order is going to be an undefined value in fact if you hover over order here you'll see the intellisense popup it says const order Colon capital O order and then a pipe character or a line and and then undefined similar to JavaScript with the double pipe operator indicating an or logical operator I like to read this single pipe in typescript like the word or as well in other words const order is either going to be a capital O order object or it will be undefined and that's because typescript knows if it's not able to find something with the finded method it will return undefined and in this case we're not handling that in our code typescript saves us again so if there is no order then maybe we'll just do what we did above where we console error let's say order ID was not found in the order que and then we'll go ahead and return although as I mentioned before this could be an opportunity for us to throw an error if we were to throw a new error and then maybe put this message in there that would work just as well because it halts the execution of this function and therefore typescript is now satisfied that order. status is never going to get reached if order is non-existent but just to stay consistent I'll go ahead and keep my return here clean up the challenge text and look at that all the typescript warnings in our app are gone now I do think it's important to note that the lack of typescript warnings doesn't automatically mean that our program will function exactly as we expect it doesn't mean that we've handled every Edge case but it does mean with relatively little amount of effort we have a much greater degree of confidence that our app is going to work as as we would expect speaking of which we haven't run this code in a while let's run it and open our console and Awesome everything looks the way that we would expect in order for us to touch on a few more topics in typescript we are going to start building out new features in our pizza restaurant app but before we do that I do want to encourage you to get your hands on this code play around with this try adding some new functions or making some kind of change it doesn't even have to be significant for example when I was first writing this I decided I actually wanted to rename the to order history and if I do that suddenly we get some errors immediately showing up in our typescript that are super helpful they help us know exactly what needs to change in fact I'm going to leave this as order history so that I can bug some of you into fixing this error and getting your hands on the code once you feel pretty comfortable with everything that we've written so far let's keep moving forward hopefully you've had a chance to play around with the intellisense popups that happen when you hover over different variables that you deare with typescript and something you might have noticed is the difference between how typescript infers different types for example if I were to say let my name equal the string Bob go ahead and hover your mouse over my name okay you'll see that it says Let My Name colon string so typescript has correctly inferred that my name is of type string and it will warn me if I were to ever try and change it to a different data type you can see here typescript is saying that you can't assign the value true to a string type variable okay let's see how that differs however when we use const to declare our variables so if I say const my name equals Bob and I need a different variable name let's say my name 2 cuz I'm really original right now C your mouse over my name 2 this time the popup doesn't show the type as a string but instead it shows the type as the string Bob this is called a literal type and it's when you tell typescript that the type isn't a generic string which would allow that variable to be become any string but instead it's a literal type an actual value type of the string Bob with a capital B at the beginning if you put a little bit of thought into it then this will make sense because with let I am allowed to change the value of this variable and typescript logically restricts the data type of the value I'm allowed to change it to to a string and with const I'm not allowed to reassign this value and so it makes sense for typescript to say this value has to be the string Bob from here on out I can't say my name to equals bill this not only makes sense in typescript but also JavaScript we would get warned in regular JavaScript saying we can't reassign a const and if you hover over my name 2 here it says cannot assign my name 2 because it is a constant or a readon property just for the sake of completeness I can manually type something to be a literal type so I could say const my name to colon the string Bob equals the string Bob of course typescript already inferred this but this is what that syntax would look like I could do the same thing with my let I could say Let My Name colon the string Bob equals Bob and if I were to try and change this to anything else like Bobby then I get a typescript warning the same thing would happen down here now there are times where you may see this being useful in typescript but more often than not the concept of using literal types is much more commonly found when you pair it with a concept called unions so feel free to around with this code and in the next Grim we'll learn about what unions are as I mentioned there certainly are going to be times when a literal type by itself can be useful however you will often times see them being used combined with a concept called unions let's start with an example let's say we are working on an application and we want to maintain a different kind of user role for the sake of our database and our application we're going to be saving that user role either as guest or member or admin and in our app we don't want someone to be some kind of user R like a hacker or something completely gibberish that doesn't make sense to our application in this kind of scenario we can use a combination of literal types and this concept called unions to teach typescript that this variable user role should only be allowed to be one of a certain number of strings if you're familiar with the concept of enums in other languages this is essentially the same idea as an enum there's a little bit more to be said about that because typescript does have something called enums but let's not get bogged down by that topic for now if you're not familiar with the concept of enums well you already are familiar with the concept of an enum because you know what a Boolean is a Boolean can only either be true or false it has to be one of those two values and it can't be something like yes or no at least not in JavaScript so if we have our user role and we want this to only ever be guest member or admin we can use Union types in order to accomplish this I'm going to create a new type called user Ro and I'm going to set it equal to the literal value of guest and then I can make a union by using the single pipe character you can essentially read this just like you would the double pipe character in JavaScript as the English word or so I can say that type user Ro is either going to be the string literal guest or the string literal member or the string literal admin and now that I've defined what a user roll type is allowed to be I can tell my variable that it has to conform to the user Ro type and from then on if I were to ever change this to some gibberish typescript would give me a warning this literal Union type that we have here doesn't just need to be its own Standalone thing I might have it nested inside of another type so I might have a user type which has all of the other properties that we might normally see like a username of string blah blah blah and then I might say user r or let's just call it role and we can just copy what we have here and say that the user. roll property has to be one of these three string literals I won't necessarily go down and show an example because I think you get the idea let's go ahead and satisfy typescript by making this one of the available options inside of our user roll Union and typescript is satisfied okay let's jump back to our p a restaurant app there's a really small update that we can make now that we understand literal types and unions we can add a little bit of extra type safety to our orders by teaching typescript that an order type is allowed to not just be any string but it either has to be the string ordered or the string completed this should be pretty straightforward will make this a quick challenge go ahead and update our order type so that the status property can only ever be the string ordered or the string completed then once you've done that try to make a change in our code maybe change this status to something other than ordered or completed some gibberish will do and make sure that typescript is complaining about that change pause now and work on this challenge okay we'll just make this so that it can't be any string but it only can be the literal value ordered or the literal value completed now that we've made this change we can actually see there's a new typescript warning and that has to do with this line 35 where we have new order this one can be a little bit confusing to understand but let's walk through it step by step here we're creating a new order variable and we're setting it equal to this object literal when I hover over New Order we can see from the intellisense popup that it was able to infer essentially the shape of the object as having an ID that's a number a pizza which is a object with a name that's a string and a price that's a number and then a status that's a string however now that we have gotten more specific in what our order should look like up here where it has to be the string ordered or completed not just any kind of string the object that we're trying to push into our order queue which if you remember we specified needs to be an array of orders the data type that typescript inferred for our status right here is just a generic string I know this can be a little bit confusing don't fret too much if none of that is making any sense but the way that we can fix this error is by saying when we are instantiating a new order we can tell typescript specifically this is going to be of an order type by manually typing this as a type of order it now knows that the status of ordered here is not just any old string it is conforming to the status literal Union type that we defined up here and because of that order Q which needs to be an array of orders is okay with us pushing in a new order and if I were to try and change this to something like blah blah blah now typescript is complaining again because it knows that that's not okay it can't just be any string it has to be one of either ordered or completed so let's go ahead and change this back the same thing would happen if I come down here and I change this to blah blah now typescript is not going to be happy with me updating order. status because it knows that blah blah is not one of the legitimate statuses for our order object as always play around with this code and once you're ready we'll keep moving forward as we've talked about typescript is great at inferring primitive types and other more complex types that don't necessarily hold a lot of weight in the functionality of our app however there are certain times when we would really want to make sure we manually include the type of something for example here in our menu we're defining the menu as an array of these objects and these objects just so happen to conform to our type of pizza but we haven't actually told typescript that our menu should be an array of pizza items this becomes a lot more apparent when we try to make a definition change to our type of pizza Let's see we were tasked with creating a new helper function called get pizza detail which allows us to find one of the pizzas in the menu either by its ID or by its name well currently we don't have IDs in our pizzas and so we might think to come up to pizza and say this should also have an ID that's a number and doing this because it's typescript really helps us out further down the road when we find out some of our code is not going to work the way we think because they don't have IDs when we're trying to add new pizza and so forth but I'm not concerned about this quite yet we'll get to that later but notice that our menu does not have a problem with the change that we made to our pizza type definition because it doesn't know that it's an array of pizzas so let's go ahead and type it as an array of pizzas okay now typescript is warning us hover your mouse over menu and you'll see that it's complaining about how there's an ID property missing in these objects here great that's a good warning that just saved us some trouble so I'm going to go ahead and add a manual ID property here and we'll just kind of make them increment manually notice if we scroll down we used to have an error I think it was here on New Order because the pizza we were adding did not have an ID and pizzas now need IDs but we are correctly getting errors down here with add new pizza because these ones don't include IDs for now I'm just going to manually add IDs here as well this is just a temporary fix until we figure something else out what we just saw is a perfect example of how typescript doesn't make your job harder as a developer it actually significantly improves your ability to add new features and to debug your code in the process all I had to do was make an an update to my pizza type and typescript immediately showed me where all of the problems with that change would happen and I was able to pretty quickly go in and fix them granted the fix will not always be quite this easy but hopefully you're seeing the benefits nonetheless next we'll move on to a concept called type narrowing and we'll do that through a series of challenges to start us off on a lesson about type narrowing I'm going to give you a challenge I want you to create a new utility function called get Pizza detail it's going to take a single parameter called identifier but there's a little twist to this we want to allow this identifier either to be the string name of the pizza like the string pepperoni or it could be the ID number of the pizza for example the pizza with the ID of the number two you don't have to worry about the code inside of the function just yet I just want you to create the function signature and just make sure that you type the identifier parameter correctly so that typescript is okay with it either being a string or a number type I haven't taught how to very specifically do this one thing but assuming you've been following along and doing the challenges I think you'll be able to put this one together pause now and work on this challenge okay let's create a function called get pizza detail it's going to take identifier as a parameter and we're going to type this identifier as either a string or a number and this is what I meant by saying we haven't specifically taught this thing we talked about doing it with string literals if we wanted it to literally be one value or another value but we can also use unions with more generic types like you see here okay let's start working on the internals of this function and really what I mean is I want you to do this I'll make this into a challenge I'm getting a little bit more vague with the details of how to accomplish this challenge but that's okay cuz I know you're to the task I want you to write the code for our get pizza detail function so that it's able to use the identifier whether it's a string or a number and use the menu. find method accordingly once one of the pizzas from the menu has been found it should return that pizza for now you can just assume that it will find something in menu. find you don't have to handle the instance where it might not find something pause now and work on this challenge okay let's get started on this in JavaScript we can determine what kind of data type identifier has by using the type of keyword and so I'll use an if statement that says if the type of identifier is a string then I can assume that it's going to be the name of the pizza and so I will return whatever comes back from menu. find and we'll say for every Pizza that we're looking through if pizza. name is equal to to the identifier then it will find the correct pizza and return it one little feature I think I'm going to add is I'm going to lower case both of these just so that if they put in the wrong capitalization for the pizza name or something like that then it will still be able to find the correct pizza now for the next part I'm going to just use an else instead of an else if checking the type of the identifier to be a number but I'm doing this specifically so that I can show a limitation of being less specific for now we'll essentially return this exact same line except instead of name we're going to check the ID and uh we don't need a to lowercase because that's going to be a number and actually check this out if we hover over to lowercase typescript is able to tell us that do to lowercase does not exist on type number this is super interesting because it highlights the fact that typescript is able to parse and understand our code and it knows that we have already handled the instance where the ident ifier might be a string and because we've told typescript that the identifier is either a string or a number it knows that in this case according to what we have told typescript the type of the identifier will be in this else statement it has been able to narrow the type down to be a number also if we were to have copied this line of code down and simply removed the dot to lowercase but forgot to change this from name to ID typescript warns us that we can't use the trip equals to compare a string which it knows pizza. name is and a number which now that we have narrowed the type down we know that it is no longer going to be a string if it's reaching this code and so it's able to warn us that these things aren't going to equate correctly so just another instance of typescript helping us out so this is just one example of this concept called type narrowing where when we're writing a function and we don't necessarily know what the data type of that function is typescript will expect us to narrow down the type and handle each use case or potentially provide a default for all other use cases if it isn't in the if or else if statements soon we're going to see another example of where type narrowing is really important but first I want to address this lse statement that we have as I mentioned I would we'll do that in the next scrim although this isn't a specific benefit created by using typescript one thing that writing your projects in typescript will help you do is remember to be as explicit as you can when you're writing your code for example I have told typescript that my identifier is either going to be a string or a number and I've handled the case where the type is going to be a string and therefore typescript can assume that inside of my else Clause here the type will be a number however in some instances you may be working in a project where the code you're writing will end up being used in a plain Javascript file and the protection that other file would normally get if it were used using typescript won't exist so I've added this export in front of our function and I'm going to use this index.js file to import our get pizza detail function from our index.ts file and I can show that this is working so I can say get pizza detail with the ID of one and we'll console log the result and sure enough we get our margarita pizza with the idea of one however Nothing is Stopping this Javascript file from doing something weird like saying get pizza detail false because it's JavaScript we're not going to get any compile time warnings here and so I can run the code and get the value of undefined which in all honesty our function is pretty okay with returning anyway but we could get a little bit better of a user or I guess not a user but another developer's experience can be improved if we're just a little bit more explicit here and we say something like if the type of identifier is equal to a number then we can run this code and then we could include another else that maybe throws a new type error that says the parameter identifier must be either a string or a number okay so let's hit save and now by trying to use false in get pizza detail we get our type error thrown so that the developer using a Javascript file can get a little bit more of an intentional feedback loop so long story short when you're writing your typescript code try to be as explicit as you can within reason staying on the theme of being explicit with your typescript code whenever you can I want to talk about function return types before we jump into that though I did want to note that we previously talked about composing together different object types but here we can see we have this type user and for the RO property of that user object we're using the user R type that we created up above so we can compose types together however we want it doesn't just have to be when we're talking about nested objects like we saw at the beginning of the course okay so here we have a users array and we have a function called Fetch user details which takes a parameter of username and sends back the user in its return value go ahead and hover your mouse over the name of this function fetch user details and you'll see that in the popup it says function fetch user details parentheses username colon string exactly what we have in the beginning of our function here in our code but then it says colon capital u user the colon that we put after the arguments of our function gives us a chance to specify what type of data should be returned from our function now typescript was able to infer that as we see it put a colon user there but in a lot of instances it can be really helpful to explicitly type what should be returned from your function so I would put a colon and this is between the arguments of my function and the opening curly brace and then I would just put capital u user here to teach typescript that this function should always return a user object so if it was able to infer that it's returning a user why is it helpful to explicitly put a capital u user here well one of the major reasons I think for doing this is that it helps whenever we're refactoring our code if myself or some other developer were to find this function and say I don't know why it's returning a user it should be returning the user. username instead well if they try to do that then they will get a warning from typescript saying that it's trying to return a string instead of explicitly a user object if I don't include this explicit typee declaration then typescript has no problem with me completely changing the return value of this function which assuming this function is used throughout my codebase would likely cause some other problems so this is an opportunity for us to be a little bit more explicit and to specify that we want this to be a user object that gets returned and if someone is going to change the return value of this function they would have to come up and explicitly change this to something like string and this would be the dot username which theoretically would be a prompt to that other developer or myself in the future to then go throughout my codebase and make changes every time we're calling this fetch user details function let's keep this returning a user for now okay it's been a minute since we've had a challenge so let's go back to the the pizza restaurant app and try your hand at a quick challenge we just talked about the typescript specific type called void and there are actually a few other typescript specific types that I think would be worth taking a little tangent to talk about at this time we'll start with a rather notorious type in typescript called any the easiest way to think about any is to know that if you type something with any you're essentially turning off typescript checking for that value so if I have a value and let's set it equal to one typescript is able to infer that this should be of type number you can hover your mouse over value to see that and it gives me warnings if I ever try to do something like reassign it to a string it tells me that you can't do that or if I try to run an operation on it like to uppercase which only works for Strings it tells me that you can't run this method on a number These Warnings of course as we've seen up until now are very useful to us but let's see what happens if I manually type this as an any type suddenly the warnings go away as I mentioned we've turned off typescript checking so I can tell value that it's going to be a string now I can try to call say an array method on it and typescript isn't going to warn me at all essentially it's a way to say in your code I know better than typescript how this thing should be typed and I don't want typescript to help me at all I think you can probably see maybe from my tone or just from the lack of warnings here that this is not a good idea so when really should you use any well in short you shouldn't it can be tempting when you're looking at your code that has a bunch of typescript Errors to just throw your hands in the air type things manually as any so that the warnings go away and then continue on with your code but in that case why did you choose typescript in the first place now that's not entirely fair I think there is at least one legitimate use case and I think that would be if you're in the process of transitioning your code base from JavaScript to typescript and you don't have the time right now to write all of the complex types and update all of your code to satisfy the typescript warnings and you just need a temporary that's the important part here temporary way to get around typescripts just for now but be warned as soon as you start adding any to your code base and the warnings go away it might be a bit difficult to go back and force yourself to bring those warnings back by removing the any types in fact it might be better if you just left the warnings there and turned off the configuration in typescript that forces you to satisfy the typescript warnings before your code will compile we're venturing into territory outside the scope of this course so if there's just one thing I want you to take away from this lesson just don't use any if you do have a scenario where there's a value where you legitimately don't know the type of it there's another typescript specific type that is much better suited for that scenario and it's called unknown that's what we're going to be looking at next okay we're going to do this in a couple parts the first part of your challenge is to add a return type to the get pizza detail function this should take you all of about 2 seconds to do but once you do it as it says in the note you are very likely going to get a giant typescript warning but don't worry about that we're going to address that in part two of The Challenge pause now and add a return type to our get pizza detail function simply enough we can come between where the closing parenthese is in our parameters and the opening curly brace we can just put a colon and say that this is supposed to return a pizza and look at that we get those giant typescript warnings and if we hover over it it tells us that type pizza or undefined is not assignable to type pizza now before I explain exactly what's going on here I want you to think about it try and figure out why is it saying that the type pizza or undefined is not assignable to type Pizza in fact if you want to pause to spend a little bit of time playing with the code or thinking about that go ahead and do so now we talked about this briefly when we first wrote this code but remember that menu. find potentially returns an undefined value if it's not able to find the pizza that you specified let me get rid of my explicit declaration here and for a kind of unrelated reason I need to get rid of my challenge text and now hover your mouth Mouse over get pizza detail and you'll see that it did infer what data type would get returned from this function it's either going to be pizza or undefined typescript was smart enough to read through the code and know that we are returning potentially an undefined value or rather a value of undefined inside of our code here and so it inferred the return value as either pizza or undefined this is where things can get a little bit hazy you may want to rewrite your code a little bit differently to either throw an error if it was able to find the pizza or you can just expect that whatever code is calling get pizza detail will handle the instance where it gets an undefined value returned but since this course isn't about how to architect this particular function we'll go ahead and do another really simple challenge okay again really easy but I want you to explicitly type the return value of this function so that typescript knows it could either be a pizza object or the value of undefined pause now and work on this challenge again simply enough we can just put a colon right here and say it's either going to be pizza or we will include the union of undefined like we saw before this doesn't necessarily change the way that the function works or the way that typescript sees the function but it does help us or other developers in the future know that when we're messing with this code and doing some kind of refactor we need to either make sure that we continue to return a pizza or a value of undefined or we need to explicitly change this value and then change our code everywhere else that's depending on get pizza detail either returning a pizza or undefined let's clean up the challenge text all right well we're not quite done talking about return types with functions so feel free to play with the code as always and when you're ready we'll keep moving forward there's another return type that isn't quite as obvious as something like pizza or undefined was down here and that is when you have a function that doesn't return anything look through the code on your screen here see if you can find a function that doesn't currently return anything hopefully you found this add new pizza function in fact if you hover your mouse over it you'll see that the inferred return type is called void this function modifies the menu by pushing new objects to it but then there's no return from it there's not going to be a value that we can get from it so one way we can be a bit more explicit almost like documenting our code in line is by explicitly typing this as returning void it doesn't change the way that the function operates if you try to save the return value from calling add new pizza you would get the value of undefined but it helps us or other developers in the future reviewing through this code to know that we knew this wouldn't return anything it's just performing an operation outside of itself and then not returning anything that's about all there is for me to say about void it's pretty straightforward but since that was pretty quick I want to give you a relatively unrelated challenge okay your challenge is to add explicit return types to the rest of our functions so really just the place order function and the complete order function pause now and work on this challenge a really easy way to do this is for us to hover our Mouse over the name of the function and see what typescript has already inferred is going to be the return type here we can see that it's either going to be an order type or undefined and if we go to complete order it's actually going to be the exact same thing order or undefined so really just getting our repetitions in with the muscle memory in typing these functions out okay nice work let's move on let's take some time to do a really simple refactor to our code and see how typescript helps us do that currently when we're creating the menu we are manually adding our IDs here with 1 2 3 4 and I brought the calls that we had down at the bottom up a little bit to add new pizza and we were manually doing IDs of 5 six and 7even let's go ahead and use the same trick that we're using with next order ID right here where when we are creating an order we are creating an object right here where we're using next order ID ++ if you run into any typescript errors make sure to hover your mouse over them and see if you can figure out how to fix them as a little peek into the future for now we will still keep the IDS here inside of our add new pizza call but my goal is to get us to a point where we can submit a partial Pizza object without the ID and have the function handle adding the ID for us but for now we'll skip that part pause now and work on the challenge so I might want to come here and say let's call it next Pizza ID and we'll start it off at 1 and then up here instead of one I can say next Pizza ID plus plus and check it out we're getting an error from typescript you probably already know what this is but if we hover over this it says the block scoped variable next Pizza ID is used before its declaration variable next Pizza ID is used before being assigned and yes it is down here on line 22 we are defining that and because of the way hoisting and everything happens in JavaScript this would actually need to be above where we're using it so let's just move all of these Global variable declarations up here to the top and then we should be fine typescript is already helping us out okay we'll do the same thing here and there and down here when we're adding new pizzas we will go ahead and do the same thing down here at the bottom I am still console logging the menu and then a couple other things that we actually don't care too much about right now okay so I'm adding three new pizzas down below I am still console logging the menu we'll comment these other ones out for now and let's open our console and hit save and perfect we have our menu with all seven items in it now let's address this issue where it seems a little strange that we are providing a pizza object but we are in charge of ensuring that the ID is being handled correctly it seems like the add new pizza function should be able to handle that for us so I want you to test that out I'm going to write this in as a challenge okay I'm calling this challenge part 1.5 because there's a topic in typescript we still have to learn in order to do this without typescript complaining at us so as you'll see in the note you're still going to run into typescript warnings that we are going to address soon but the code should still run if you do it correctly the goal is to make it so that we don't have to provide this ID property when we're adding a new pizza we just have to provide the information that's specific to the pizza and we can move the assigning of the next Pizza ID inside of the add new pizza function as an implementation detail of this function it's not really something that we should have to think about when we're adding a new pizza to our menu we really only want to provide the details that are specific to the pizza okay I think you should be ready pause now and work on this challenge okay well the pizza object that we are about to receive will be essentially the same as before but without an ID and so I'm going to before I push it to the menu we're going to say pizza object. ID is equal to next Pizza ID and then we'll use the plus plus trick to increment it to the next number so that the next time it runs it's already changed and then this is where typescript is going to yell at me I'm going to get rid of these ID properties in the objects that I'm passing and sure enough typescript is screaming at me here it says that I'm missing a property in the pizza object and I'm typing this as a pizza object but let's go ahead and hit save and we open up our console and sure enough we get the same results that we had before we have the seven pizzas in our menu and they have an incrementing ID just as we would expect okay next let's address why typescript is screaming at us and how we can fix it in this lesson we're going to talk about something called utility types but in order to set this up I'm going to have just a really quick challenge for you you can see here we have a user type this is something we've seen before we have an array of users that are typed as an array of users and your task is to create this update user function and what it should do is take a number ID as its first parameter and the second parameter is an object that we're calling updates and this object will not be a full user object it's going to only contain the properties that you want to change I've explicitly typed these as any just so that for now we can turn off typescript then we're going to learn about utility types so that we can type these the correct way and actually you know what just to follow my own advice this should be typed as a number because that's not really what we're going to be talking about in utility types now I've given you the instructions on how to do this this is intended less to be about doing algorithmic thinking and more to just get your hands on the keyboard and make sure that you're staying active in this course so you'll simply use the array. find method to get the correct one based on its ID then you'll use object. assign so that you can update the found user just right there in place if you aren't familiar with object. sign or you're a little bit resy on it you can do a quick Google search to find how to use it okay pause now and work on this challenge okay let's go to we'll say users. find and this is going to return a user we'll call it found user and this will take a function a callback function will say for every user that we're looking through we want to find the one that has the user ID that's equal to the ID that's passed in here in the update user function okay we can move this comment up there let's go ahead and handle the scenario if there is no user so if there's not a user and this should be a found user let's just put something in the console we'll say user not found and then we'll make sure to return so the rest of the code can't run okay and then we'll use object. assign this will just change the object directly in place this may or may not be the best way to handle it but it's the most straightforward way so we'll set the found user as the starting object and then we'll replace any of the properties that are found in this updates object we can get rid of this comment and yeah we're console logging users down here let's run this code and let's see we're specifically looking for the user with the ID of one and sure enough the username is now new John do and the last one with the username of Charlie Brown does have the role of contributor instead of member perfect okay why are we talking about this well obviously as I've mentioned we shouldn't be using the any type here however we're not able to use user as our type here because we're not providing a full user object it's also important to know that because we don't know which property is going to be passed to this function or potentially multiple properties we can't come up and just create a new type like an updated user because what exactly are we going to put here we could say that it's going to be a username that's a string but then what are we going to do if it's a Ro change instead well you might be thinking well what if we just take every property from user and we make it optional so we say I don't know maybe there's a way that we'd ever want to update an ID we'll say well the ID could be a number and we'll put the question mark here to say that that's an optional update and we might have a username so we'll set that as optional and we'll say that's going to also be a string and you know what this is pretty much a lot of duplicated stuff so I'll just go ahead copy this one down put a question mark there okay great well we've done quite a bit of extra work here we would then be able to say this isn't going to be a user it's going to be an updated user now we come down and we can see that typescript is no longer complaining not only that but we run our code and things are working like they were before well this was a lot of busy work imagine if we had a type that had 15 properties on it that'll be a bit annoying to have to copy those over and just make everything optional and at least as far as this code is concerned we're only using this type in one place right here for our update user function so this is where the ccept of built-in utility types comes from in typescript there are a number of types that like a function they can take other types in as a parameter and they will return a new type that you can use with a few changes made to it and these are things that are built directly into typescript their whole goal is to perform some commonly needed modifications to existing types so that you can continue to work within the typescript system kind of like we did here instead of creating updated user manually by copying all of the properties and then making them optional we can use a utility type to accomplish this we're going to talk about that in just a second the other thing to know about utility types is that they use something called generic syntax which uses angle brackets now this is just touching the surface of that we are going to talk about generics very soon in our case here with the update user function we can use a built-in utility type called partial and what the partial type does is it takes in the type that you pass to it in our case we want to make a modification to our user type that we built and it returns turns a new type that has all of the properties set as optional that should sound familiar cuz that's exactly what we just did manually if you want to learn more about the partial type click on the screenshot here this will take you to the typescript documentation specifically on the partial type okay what does that look like well instead of manually typing this out I'm going to use the built-in type called partial it's got a capital P and I use that angle bracket syntax that we saw right here because this partial uses something called generics again we're going to talk about that in the future but you can kind of think of it like if partial were a function you would normally put parentheses but because it's a utility type and not a function we use angle brackets instead and we pass our user type in as a you could call it a parameter or in this case it's really a generic type to this partial and as we saw what it does is it takes this user in and it returns a new type which we're calling updated user and if you go ahead and hover your mouse here over updated user you will see that it has a type already defined for us where all of the properties ID username and role are set as optional this way when our update user function takes an updates object and its type is updated user we can provide an object that is missing some of the properties from a user object we've used this partial utility type to minimize some of the boilerplate code that we would have had to write manually ourselves if you take the time to go over to the documentation by clicking the screenshot you will see that there are a ton of built-in utility types tyes in typescript and so this might be a good time to click this if you didn't already just peruse those play around with the code that you see here feel free to come up with different examples we are going to talk about one other utility type because it's going to directly relate to what we're working on with the pizza restaurant app but there is a small caveat that we'll need to work around we'll talk about that in the next lesson this lesson's going to be nearly identical to the one we had before but as another way to to drive forward the curriculum in learning a new utility type to start off to make sure your hands are on the keyboard and that you're awake as you're going through this course I'm going to have you create the logic for a new add new user function it's going to take a new user object and in this case the new user object will not have an ID provided to it as you can see in the example usage down here it will have all of the properties except for ID so for now I've typed this as any and the return for this function needs to return an actual user object that does have an ID read through the comments here to see the specifics on how to create that it basically tells you exactly what to do and when you're done the typescript errors should go away but then we'll address this issue with having an any type here also for Simplicity I've added this next user ID variable and added it to our users array just so that you can continue to use next user ID Plus+ like we were doing in the Pizza app and I've also shortened this users array just so that there's not quite as much clutter when we're console logging the array of users okay you should be set up pause now and work on this challenge we can pretty much just follow these steps exactly as they're said so we'll call a new variable user and I'm actually going to type this as a capital u user the goal is to make sure that it conforms to the user object type okay this is going to be an object and the first thing I'll do is add an ID property to it we'll use the next user ID Plus+ to get that in there and then I'm just going to spread all of the properties of new user into this object now that I have a new user object or a user object that is new let's go ahead and push it to the array of users we'll say this is users. push user and return the user objects okay now the typescript warning under user is gone because now this function is returning a user as the type would indicate it's supposed to let's clear out the comments here and do just a quick test we're pushing Joe Schmo who is a role of member and sure enough there he is at the end of our users array with I might add the ID of three which is what we wanted this might be a good time to remind everybody watching this that this whole next user ID thing that we're doing it's really just to drive our curriculum forward you're very likely to have your database handling the whole ID assigning thing okay now let's address this any type here we don't really want this to be in any type because as it currently stands we've disabled typescript checking for this and I could just add a blah blah category or property to this object and typescripts not going to warn us that this isn't going to work or rather that it could really screw up our code so what exactly can we do well we just learned about the partial type and it might seem at first glance that we could make this into a partial of user however the problem with the logic here is we want to make sure that all of the properties exist and with partial it turns everything into an optional property let me get rid of this blob property here if I submit this as a partial like this of user and then for some reason I don't Supply one of the properties here I have a problem I've taught this function that it's going to return a full user and as you saw even before I deleted the RO property here we have a warning and it essentially tells us that these are not going to be compatible that's because we need to return a user and our user property needs to have up here it's not optional to have an ID a username and a role but our partial user type here it is possible to not have one of those things because all of the properties are optional okay so partial is not really going to work for us there is a way clearly that we could make partial work but we would have to do a bunch of extra checking inside of the body of our function and that's not really the road that I want to go down enter the omit type what does the omit type do well it takes in a type just like partial but it also takes you could call it a second parameter to that utility type which will be a string or potentially a union of strings we'll see what I'm talking about in just a second and those strings are the property names that we want to Omit from this type it's going to return a brand new type with the properties that we specified removed it would probably be a great idea to go to the documentation on the typescript docs you can click the screenshot that you see here which should take you directly to the omit type docs so what does this look like for us well often times especially if you're only going to be using this utility type once in your code you can just do it right in line so I can use capital O omit a set of angle brackets and I first need to provide as the first parameter you could say the user type or the type that I'm trying to modify and then just like in function parameters I'm going to add a second parameter here and that is going to be a string of the properties that I want to Omit from the user type so that the type that omit returns will not have the ID property in it okay why is typescript warning us about capital O omit well we come to another point of some irony the omit utility type is currently omitted by scrimba well more specifically in reality it's just that omit was introduced in typescript version 3.5 scrimba is currently running on an older version that doesn't yet know what omit is in the future I'm going to be able to remove this whole caveat but for now I'm just going to show you a screenshot of what it should look like so we have our code exactly like we see here and notice that typescript is not warning us about anything I guess as a reminder typescript doesn't stop us from running running our code there are ways to set it up to do so but I can hit save I can open my console we can see that our joeo user has been successfully added to our array but let's look at what it's supposed to look like if I were to for example comment out the ID property we can see that we have an error on the user object if we hover our Mouse over it we can see that the property ID is missing that's exactly what we would expect now I don't have a screenshot of this but if we were to take away one of the properties when we're calling add new user we would also get a typescript warning that tells us that we're not providing the correct type to our add new user function it's going to have all of the properties of user just minus the ID property that way our function can be in charge of creating the ID for our user object really quick I did mention that you can provide either a single string or a union of strings if for some reason I wanted to Omit both the ID and the username I would use a union character which is the single pipe and I would do another string literal of user which tells it that I don't want this new type that omit is creating to contain either the ID or the user in our case that means it would just be an object with a ro property again typescript would be warning us here but because it's not currently recognized by scrimba it's not giving me any other warnings okay it's time for us to get back to our Pizza app and apply what we've learned specifically about omit so that's what we'll do next let's apply what we just learned about omit to our pizza restaurant app specifically the add new pizza function your task is to fix it so that we use the omit utility type just like we did in the previous lesson we want the user of this function to provide a pizza object that does have a name and a price we don't want those to be optional because we need that information in our menu but the add new pizza function will be in charge of adding the ID to it while we're at it let's go ahead and change this function so that it Returns the new pizza object instead of void I'm just going to add that here to the requirements okay so make sure that you return the new pizza object with the ID added from the function which means you'll have to change the types here as well as a quick reminder at the time of recording this the scribit environment doesn't understand the omit utility type so you will get a little red squiggly under the word omit but you can safely ignore that and essentially any other typescript warnings you see here in the very near future scribo will know about omit so I'll be able to just remove this caveat the time is yours pause now and on this challenge again the reason we want to use omit and not partial is because we want to require that the person submit a pizza object with all of the other information except for this one property of course with omit you can omit more than one property but in our case we just want to Omit from the pizza type we want to omit the ID property like that and while we're up on this line we decided we're going to return a full Pizza object from this function currently we're not doing that so typescript is warning us now we have an issue with the way that our code currently is set up because we just told typescript that this pizza object will have all of the properties of pizza but not the ID property in other words it's going to have a name and a price and then we're trying to add an ID property on top of it well we can't do that so let's go ahead and create a new pizza object we'll call this new pizza we're going to to type it as a full Pizza object and we'll set it equal to an object we'll give it an ID property we'll use the next Pizza ID and then add the Plus+ for the next time around and then we'll spread in all of the properties of pizza object we'll get rid of this line of code and instead of pushing Pizza object we will push new pizza I can hardly believe how many times I've said the word pizza and then as we described up above we need to make sure we return the new pizza object let's hit save and we are adding a few new pizzas up here we're console logging the menu and sure enough we have the chicken bacon ranch the barbecue chicken and the spicy sausage pizzas added for the time being while scrimba doesn't understand the omit utility type I have a couple screenshots here so this is from VSS code we can see when we add the omit Pizza type up above typescript is happy with everything the exact way that it is if we comment out ID then typescript isn't happy if you hover over new pizza it tells you that you're not allowed to push this object to the menu because menu requires Pizza objects and this object that you're trying to push does not have an ID so let's go ahead and put that back in similarly if we were to come down and say remove the price from this first pizza that we're adding we get a typescript warning that is a little bit cluttered here but essentially tells you that the property price is missing now for the sake of this course I've decided that it isn't my objective to teach every single utility type that exists because the documentation is very straightforward if you want to peruse and see the different types that there are again you can click this link this will specifically take you to the omit type but it's all one long page in the typescript docks so you can scroll around and see all of the different types there but hopefully the idea is starting to be clear these utility types perform really common operations on your existing types so that you don't have to do this work by yourself and introduce a bunch of repetitive code now I did promise earlier that we would address this issue here where we have these angle brackets and I think this would be as good a time as any to jump into that which is a topic called generics so that's what we'll be learning about next I've mentioned this term generics a couple times throughout this course and so it's finally time for us to learn what generics are generics and typescript are a really powerful tool that allow us to add some flexibility to the types of our existing functions are already existing types and other aspects of typescript code you can kind of think of it like a function parameter a function parameter is a placeholder for a real value that you use throughout your function and a generic is a placeholder for a type that you can use throughout your function or whatever aspect of typescript you're using your genericon this will make a lot more sense when we see an example and generics use this bracket syntax with the angle brackets that we've seen a few times already in our code let's see a bit of a contrived example here and then we'll apply what we've learned to our pizza restaurant app let's say we have a few different arrays like we have on lines 1 2 and 3 and we want to create a really simple utility function that's called get last item it takes an array as a parameter and since this isn't really part of this challenge I'm just going to say in order to access the last item of an array in JavaScript we can just return the array at the index of array. length minus1 Okay we can see there's a red squiggly here for array hover your mouse over the word array and you'll see that it says the parameter array implicitly has an any type typescript doesn't like when we have implicit any types and so one cheater solution could be to explicitly type this as an any type and of course that makes the typescript warning go away but again that's because the any type basically turns off typescript this isn't exactly what we want the problem is we can't say that this is an array of strings or an array of numbers because we don't know that it could be an array of any item okay well what are we to do then this is where generics come in into play as I mentioned just like a function has parameters that are placeholders for values generics are a way for us to have placeholders for whatever a type is going to be okay let's check out the Syntax for generics when we're using it in a function like we're doing here right before our parentheses with our function parameters we're going to put in our angle brackets and inside those angle brackets similar to how we're doing with the function parameters inside the parenthesis we're going to put a placeholder for whatever type is going going to be used with this function a fairly strong convention for this is to use the capital letter T to represent type but just to make sure that we're being explicit I'm going to use the full word type with a capital T again this is a placeholder type the capital T type here is not referring to something that's built into typescript this is a name that I chose I could have just as easily chosen blah blah blah but let's not do that okay well what can I do with this now well just like in a function I can use the parameter through throughout the code to represent whatever value array represents when this function gets called I can use my generic type here to say the array is going to be of type capital T type and it's going to be an array of that type we've used the word type quite a bit here I think it actually might be useful for us to call this something totally different like let's call it placeholder and actually I'm going to call it placeholder type because truly it doesn't matter what it is just like the name of your variable doesn't matter what it is you can call it whatever you want as long as you're consistent throughout your code okay great let's get your hands on the keyboard this is going to be very simple with more like a mini challenge than anything this mini challenge is less about solving the issue and more about seeing what the intellisense popups are when you hover over the different values so call get last item on each of the three arrays that we have on lines 1 2 and 3 you'll probably want to console log The Returned value just so that something shows up in your console and then the main thing I want you to focus on is hovering your mouse over different values in the code just to see what the intellisense popup shows so that you can get a better idea of what's going on with generics pause now and work on this mini challenge okay so let's get our console logs in here we'll just do three of them I'm going to use multiple cursors to save some time we'll call get last item and then we will put in our three different raise okay we'll hit save just to make sure that's working the way we expect great we don't actually need to see the values right now but let's hover our Mouse over maybe game scores first okay we can see that it is typed as an array of numbers that's a type that was inferred by typescript because of course we didn't explicitly type it as an array of numbers we can see the same thing with favorite things it's an array of strings and with voters it's an array of object literals okay now let's hover over get last item for this first call with game scores it shows that that it's a function called get less item and as its type inside of the angle brackets it shows number and then it used that number type to infer that array the parameter array is an array of numbers it also inferred that it's going to be returning a number as well which we didn't explicitly place here we'll do that in just a second but if we hover over this second get last item we'll see it does the same thing but with strings and on the third one it does the same thing but with that object literal with a name property and an age property doing this allows us to write types and in this case functions that can be a lot more flexible and still have some type safety without us using that any type which just turns type safety off completely now this is bothering me a little bit that it says placeholder type I'm going to go back to say type and again a really strong convention is just to use the letter T and other single letter variables which is kind of funny now that I think about it because we tend to tell people not to use single letter variables for things if you want to dive a little bit deeper into generics there is quite a bit more than what we covered in this lesson and frankly more than we're going to cover in this introduction to typescript course but you can click on the screenshot here to go directly to the typescript docs and it will show you some additional examples there that might help solidify the concept in your mind okay now I mentioned that if you hover your mouse here it says that it inferred the return type as a number but we can also do that explicitly however I want this to be a challenge even though I haven't really taught it to you yet this will hearken back to when we talked about explicitly typing function return values but with a little extra twist as we are using generics as our type pause now and see if you can figure out how to explicitly type the return value of this function in any other kind of function we put a colon after the parentheses of our function definition and we specify that this for example would be a number or something like that in our case though because our function needs to be more generic than just using numbers we can use that placeholder type generic type here as our return value it's going to be a single item of whatever type this function is currently using when it's being called now if we're really covering our bases we might also want to ensure that we know this could potentially be undefined as long as we spell undefined correctly and that might happen if we have an array of length zero all right nice work let's move on to the pizza restaurant app and see how we might apply something like this to that app the challenge that we're going to do in this lesson is purely going to be for practices sake I had to make a few changes to other parts of our code so that this very generic add to array function would work for our purposes in learning generics so once we've completed this challenge we're going to revert back to the old code we can just think of it as a refactor that's gone wrong I know the Syntax for generics can be quite a bit confusing so I wanted to make sure you got your hands on the keyboard again to type this out your challenge is to add types to this add to array function as you can see from the example usage it's essentially replacing what we had before with add new pizza and place order this is primarily where I made the changes to our old code which was using the omit utility type now we're just going to call add to array we'll provide the array that we want to add to and then the object that we want to add to that array once you've added the generic types to this function the red squigglies under array and item should go away and you should be able to console log our menu and our order queue and see these new items added to those and actually that reminds me I'm going to get rid of these so we don't have any duplicates and yeah okay pause now and work on this challenge when we're adding generics to a function right before the parenthesis we will add our angle brackets and we'll put our generic type this time I am going to use the single letter T because that does tend to be a pretty strong convention that you'll see with our array we're going to assume that it is an array of type T whatever that is in our case it's either going to be a pizza object type or an order object type which we have right up here at the top and item is going to be a single item of that same type maybe you can see why I'm saying this gets a bit confusing because we have a bunch of new characters that usually we don't see in the middle of JavaScript functions and here we can see the code says we're returning an array I suppose that will just be the new array after it's been modified and so if we hover over add to array we can see that typescript is already inferring what it will return but if we want to be explicit we can say it's going to return an array of type T let's go ahead and console log our menu and we'll do the same thing for the order que and let's see what shows up okay it's a little hard to parse but the first one that shows up in the console shows that chicken bacon ranch was added as an option on our menu and our order CU has just one item in it that is the one with the pizza from the menu at index 2 let's see that is our Hawaiian perfect we can see that the generic add to array function is correctly passing this type on if we do something like trying to add another random property to this we will get warned and it says that the object literal can only specify known properties and the property blah does not exist in the type pizza now one thing before we move on I do want to point out a little bit of a shortcoming when it comes to using our fun functions that are using generics these example usages seem to be working fine but if you remember on our order type which we have up here the status is only allowed to be the string ordered or completed but check this out if I come and I change the status see right here to something like done well typescript isn't complaining the reason it's not complaining is pretty easy to understand so we'll touch on it and fix this problem really quickly in the next lesson we have a small bug in our code and typescript is not warning us about it that's where we added our status of done even though done is not supposed to be a valid status for order types so what exactly is going on here well when we defined our generic function and we told it it was going to have generic types that it needed to use as the type throughout the rest of the code for this function when we're calling add to array both here and here we are assuming that typescript is going to be bble to implicitly infer what type it needs to use as its generic type if you hover over add to array right here on line 49 we can see that it says the generic type that it's going to take is an object literal with an ID that's a number a name that's a string a price that's a number and a bunch of other things that shows what the menu is typed as and everything like that let's do the same thing for the add to array on the order queue again make sure you're following along and hovering your mouse over this otherwise what I'm about to say will make absolutely no sense the intellisense popups shows that it's a function called add to array its type is an object with an ID number a pizza that is a pizza object type and a status that's a string interesting our status is a string but it's supposed to be the union of just these two literal strings and that doesn't seem to have come through when we're calling add to array with the order Q this is another case where it can be really helpful for us to explicitly type what the generic type we're passing into this function is to do that we essentially follow the same syntax that we had when we were defining the function right before the parentheses where we provide the parameters for this add to array function we can explicitly type it with the same generic syntax of angle brackets now this is where things can get a little tricky if this has been a bit of a challenge for you to understand so let's make this into a mini challenge just to help solidify it okay the mini challenge is to figure out what should be typed right here between the angle brackets as the generic type here here on line 53 pause now enter in the type you think should be put here between the angle brackets and when you do so the red squiggly should limit itself just to the object here at the end because done is not a correct property pause now and give that a try because in this version of add to array we are dealing with orders in the order CU we have a predefined capital O order object and when we add that in now typescript seems to be able to understand that something is not quite right with this object if we hover over add to array now instead of having an object literal as everything it has explicitly typed it as orders arrays of orders and so forth and if we hover over here we can see that the pop-up tells us the types of property status are incompatible specifically done is not allowed here it needs to be something like completed once we change it to that awesome everything is working and typescript is happy in fact if you typed this out yourself you you could start to see and this isn't going to be in the recording but if you pause it and start typing the word completed it does show up as an autocomplete option because typescript allows us to have these autocomplete options I can just hit enter and finish off the now valid completed string as our status it's probably not even worth making this a mini challenge if I do want to explicitly tell this add to array what type it should be I can again just put my angle brackets type in capital P Pizza and everything will be happy there if you want you can see the difference now hovering over add to array it tells us that the generic type is a pizza type whereas when it was gone it tried to infer exactly what that type should be and it had an object literal in our case I don't think it would make too much of a difference because we don't have anything in our pizza type like we have here with our status but once again I think both for your own readability the readability of other people looking at your code and to help typescript out a little bit it really does help to explicitly type your generic functions like this all right that was a lot of work you should give yourself a big round of applause pat yourself on the back do a little dance a little celebration we are just about at the end of this first section of this typescript course as always play around with the code I'm going to revert this back to the way it was as fun as adding this add to a ray generic function was I'm going to revert our code back to the way it was before because it was just better that way once you're feeling good let's keep moving forward and there we have it folks we are at the the end of this first section for this typescript introductory course obviously we haven't hit every last little aspect of typescript but let's recap what we have learned of course we started off by understanding basic literal and custom types in typescript then we moved on to how you can create optional properties in your typed objects we learned about unions and how you can combine multiple different types into a single type which naturally led us to learn about type narrowing so that we can narrow down which of those Union types we're using inside of our code as a side note I feel like the code we wrote when we were learning about type narrowing is a great example of how typescript really helps you learn to think more like a senior developer thinking of all the edge cases that you can while you're writing your code then we learned about a couple of the built-in utility types that give us some extra functionality in modifying our existing types in a really userfriendly way and we CT everything off by learning about generics which allow us to have additional flexibility inside of our typescript code now as I mentioned this doesn't represent everything that there is to learn about typescript and something that I'm going to be doing with this typescript course is adding to it over time so there actually is more to come at the time that I'm recording this what you've watched is everything that we have but I do plan on adding a few extra topics in this section that you just watched as well as adding entire new sections more specifically one that's focused on how you use typescript while you're writing JavaScript code that interacts with the document object model or the Dom so if you haven't already you should should subscribe to scrimba newsletter and whenever I make a major update to this course I'll make sure that we email out an announcement of those updates until then I've been your teacher Bob zero if you want to follow me on Twitter or X you can click the link that you see here my username is Bob zero so pretty easy to remember and until next time good luck and happy coding
Original Description
This course is a hands-on introduction to TypeScript. You'll learn how TypeScript can make your life easier and your code less error-prone.
✏️ Study this course interactively on Scrimba:
https://v2.scrimba.com/learn-typescript-c03c?utm_source=youtube&utm_medium=video&utm_campaign=fcc-typescript
Code is available on the Scrimba course page for each lesson.
Scrimba on YouTube: https://www.youtube.com/c/Scrimba
⭐️ Course Contents ⭐️
0:00:00 Introduction
0:06:39 Intro to Pizza app
0:16:49 Move code to TS
0:19:58 Defensive coding
0:24:36 Obligatory types basics lesson
0:28:29 Add type to orderId
0:29:55 Defining Custom Types
0:33:44 Adding a Pizza type
0:38:00 Nested object types
0:43:15 Optional properties
0:45:58 Adding an Order type
0:47:20 Typing arrays
0:52:00 Type orderQueue
0:56:13 Literal types
0:58:57 Unions
1:01:57 Update order status to use literal type unions
1:04:59 Add ids to pizzas
1:07:41 Type Narrowing
1:12:39 Be explicit whenever you can
1:14:54 Function return types
1:17:53 TS-specific types: any
1:20:48 Add return type to getPizzaDetail
1:24:11 Void return type
1:26:09 Add automatic ids to menu items
1:30:31 Utility Types & Partial
1:37:39 Omit Utility Type
1:44:42 Fix TS warnings with Omit
1:48:53 Generics
1:56:17 Generic functions in the pizza restaurant
1:59:43 Explicitly type generic function calls
2:04:08 Conclusion... for now
🎉 Thanks to our Champion and Sponsor supporters:
👾 davthecoder
👾 jedi-or-sith
👾 南宮千影
👾 Agustín Kussrow
👾 Nattira Maneerat
👾 Heather Wcislo
👾 Serhiy Kalinets
👾 Justin Hual
👾 Otis Morgan
👾 Oscar Rahnama
--
Learn to code for free and get a developer job: https://www.freecodecamp.org
Read hundreds of articles on programming: https://freecodecamp.org/news
❤️ Support for this channel comes from our friends at Scrimba – the coding platform that's reinvented interactive learning: https://scrimba.com/freecodecamp
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from freeCodeCamp.org · freeCodeCamp.org · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
React: Production Server Setup Part 2 - Live Coding with Jesse
freeCodeCamp.org
cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
freeCodeCamp.org
Browser history tutorial - Beau teaches JavaScript
freeCodeCamp.org
Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
freeCodeCamp.org
React: Parameterized Routing with Next.js - Live Coding with Jesse
freeCodeCamp.org
React: Dealing with jQuery Issues - Live Coding with Jesse
freeCodeCamp.org
setInterval and setTimeout: timing events - Beau teaches JavaScript
freeCodeCamp.org
Browser and Device Testing - Live Coding with Jesse
freeCodeCamp.org
Last Minute Updates - Live Coding with Jesse
freeCodeCamp.org
Post Launch Updates - Live Coding with Jesse
freeCodeCamp.org
React: Setting Up Google Analytics - Live Coding with Jesse
freeCodeCamp.org
React: Masonry Layout - Live Coding with Jesse
freeCodeCamp.org
Load Balancing Digital Ocean Droplets - Live Coding with Jesse
freeCodeCamp.org
try, catch, finally, throw - error handling in JavaScript
freeCodeCamp.org
Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
freeCodeCamp.org
Graphs: breadth-first search - Beau teaches JavaScript
freeCodeCamp.org
React: Masonry Layout Part 2 - Live Coding with Jesse
freeCodeCamp.org
React: WordPress API Live Search - Live Coding with Jesse
freeCodeCamp.org
Creating WordPress Custom Post Types - Live Coding With Jesse
freeCodeCamp.org
Dates - Beau teaches JavaScript
freeCodeCamp.org
Miscellaneous Front End Updates - Live Coding with Jesse
freeCodeCamp.org
Merging a Pull Request from GitHub - Live Coding with Jesse
freeCodeCamp.org
React + Prettier + Standard JS - Live Coding with Jesse
freeCodeCamp.org
React: Sortable Responsive Table - Live Coding with Jesse
freeCodeCamp.org
Geolocation Sorting by Distance - Live Coding with Jesse
freeCodeCamp.org
Tradeoff Matrix - Agile Software Development
freeCodeCamp.org
The Definition of Ready - Agile Software Development
freeCodeCamp.org
Getting first React job without experience - Ask Preethi
freeCodeCamp.org
React: Google Analytics Click Tracking - Live Coding with Jesse
freeCodeCamp.org
Submitting a PR to an Open Source Project - Live Coding with Jesse
freeCodeCamp.org
Should I go back to school to get CS degree? - Ask Preethi
freeCodeCamp.org
Hero Section CSS Changes - Live Coding with Jesse
freeCodeCamp.org
Working Agreement - Agile Software Development
freeCodeCamp.org
A day at Pennybox with Co-Founder Reji Eapen
freeCodeCamp.org
React: Sorting and Filtering Data - Live Coding with Jesse
freeCodeCamp.org
React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
freeCodeCamp.org
React: Building a New UI - Live Coding with Jesse
freeCodeCamp.org
Definition of Done - Agile Software Development
freeCodeCamp.org
Getting started with jQuery (tutorial) - Beau teaches JavaScript
freeCodeCamp.org
Making a React Blog with WordPress Content - Live Coding with Jesse
freeCodeCamp.org
React, NextJS, CSS - Live Coding with Jesse
freeCodeCamp.org
jQuery events - Beau teaches JavaScript
freeCodeCamp.org
React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
freeCodeCamp.org
React: Working with API Data - Live Coding with Jesse
freeCodeCamp.org
React: Refactoring Components - Live Streaming with Jesse
freeCodeCamp.org
jQuery effects - Beau teaches JavaScript
freeCodeCamp.org
More React Refactoring - Live Coding with Jesse
freeCodeCamp.org
animate in jQuery - Beau teaches JavaScript
freeCodeCamp.org
"Finishing" My React Site - Live Coding with Jesse
freeCodeCamp.org
Starting a New React Project (P2D1) - Live Coding with Jesse
freeCodeCamp.org
React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
freeCodeCamp.org
The Agile Manifesto - Agile Software Development
freeCodeCamp.org
jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
freeCodeCamp.org
React Project 2 Day 3 - Live Coding with Jesse
freeCodeCamp.org
The INVEST approach to product backlog items
freeCodeCamp.org
React Project 2 Day 4 - Live Coding with Jesse
freeCodeCamp.org
Chickens and Pigs - Agile Software Development
freeCodeCamp.org
React Project 2 Day 5 - Live Coding with Jesse
freeCodeCamp.org
jQuery: add and remove DOM elements - Beau teaches JavaScript
freeCodeCamp.org
React Project 2 Day 6 - Live Coding with Jesse
freeCodeCamp.org
More on: AI Pair Programming
View skill →Related Reads
📰
📰
📰
📰
Did this week show that the market cares more about new AI stories than good AI news?
Reddit r/artificial
AI Fellowship For Global Young Leaders: The Results
Forbes Innovation
OpenAI Takes a Second Crack at a Response to Apple’s Trade Secret Theft Lawsuit
Daring Fireball
Why AI-Generated Movies Are Hollywood's New Straight-to-Streaming Disaster
Dev.to · AI and Fitness news
Chapters (31)
Introduction
6:39
Intro to Pizza app
16:49
Move code to TS
19:58
Defensive coding
24:36
Obligatory types basics lesson
28:29
Add type to orderId
29:55
Defining Custom Types
33:44
Adding a Pizza type
38:00
Nested object types
43:15
Optional properties
45:58
Adding an Order type
47:20
Typing arrays
52:00
Type orderQueue
56:13
Literal types
58:57
Unions
1:01:57
Update order status to use literal type unions
1:04:59
Add ids to pizzas
1:07:41
Type Narrowing
1:12:39
Be explicit whenever you can
1:14:54
Function return types
1:17:53
TS-specific types: any
1:20:48
Add return type to getPizzaDetail
1:24:11
Void return type
1:26:09
Add automatic ids to menu items
1:30:31
Utility Types & Partial
1:37:39
Omit Utility Type
1:44:42
Fix TS warnings with Omit
1:48:53
Generics
1:56:17
Generic functions in the pizza restaurant
1:59:43
Explicitly type generic function calls
2:04:08
Conclusion... for now
🎓
Tutor Explanation
DeepCamp AI