TypeScript: From First Steps to Professional

Compiler Error Exercise

Anjana Vakil
Software Engineer & Educator
TypeScript: From First Steps to Professional

Lesson Description

The "Compiler Error Exercise" Lesson is part of the full, TypeScript: From First Steps to Professional course featured in this preview video. Here's what you'd learn in this lesson:

Anjana instructs students to declare missing types in the TypeScript files to resolve errors flagged by the TypeScript compiler. She then walks through the solution creating types, handling optional properties and type unions, and utilizing utility types like omit to manipulate existing interfaces and resolve errors.

Preview
Close

Transcript from the "Compiler Error Exercise" Lesson

[00:00:00]
>> Anjana Vakil: At this point, we have some types to create Luckily, we now have a huge toolbox full of all of these awesome syntax and concepts and wider types and narrower types and interfaces and combining types and extending interfaces and blah blah, so your mission, should you choose to accept it, is to declare the types that are missing in compile-me.ts so that the tsc --no-emit type checker runs without errors and lets us go on to our test suite after that

[00:00:47]
So head on over to compile-me.ts and take a look at what's going on there and the type errors, take a look at what the output was in the console or the squiggles in your IDE and my helpful comments and let's get some types going Types, they're not here and they need to be Help us How could anybody start me out with one type that they implemented here and what they wrote down

[00:01:33]
And ID type It's there, but it's not there Cannot resolve this So I would maybe put it just above here Is that weird And can you walk me through it Well, I just had number and then a union with string, number and then a union type with string Just there was a refresher of our syntax here How do I actually make a new type called ID

[00:02:00]
I just use ID Type ID equals number or string Amazing OK, we're just getting warmed back up to our TypeScripty syntax All right, awesome So now that's a thing, that's cool Let's try running our test command and see, OK, well, we're still getting errors, but we can start working through them Interface user extends has ID, username string, name string, and an optional email string

[00:02:37]
Awesome OK, so it was, sorry, username string, was that it was the first and then name string, and then the next one was email question mark colon string Exactly OK, awesome So email may or may not be there for a user So we're using our question mark to indicate that it's an optional property, which is basically like saying or undefined

[00:03:11]
OK, so if I save now and if I run again, we're down to errors, yay, we only have five left Awesome OK, let's plug along How about event Yes, I added host ID with the type of ID OK, host underscore ID with our ID type that we made before, fabulous And then I had date as type date, date, and so we have there is a date type in JavaScript that TypeScript knows about

[00:03:53]
So we could use that Let's try that out Cool And then I also had title as string, string And then description optional and image URL optional, both are strings OK, so we have then another couple of optional properties So we're getting real familiar with these question marks Love it And I see a whole bunch less squiggles now in the editor here, so let's just confirm that by running

[00:04:32]
Yeah, yeah, we got some more errors gone I love watching this number go down, don't you OK, so awesome Now we got a couple more left Let's see what they are And so we're getting the output on the command line here We have these two errors In VS Code also notice we have little red markers in our sidebar here that correspond to lines where squiggles appear

[00:05:01]
And so we can also get that information from the TypeScript compiler right in VS Code So that's awesome And so we have a missing type again And this is our other error is related to the fact that we're trying to add a 12 to something else And isn't it so nice that TypeScript is complaining about this and not just like giving us a concatenated string or something weird

[00:05:41]
Yeah, thanks TypeScript Thank you OK, so did anybody manage to squash these errors We can figure it out together Because it only uses a number For example, we could make the ID type not allow strings And now we have only one error left, huzzah So this is one way we could do it We can remove the string type Cool

[00:06:16]
All right, what about our missing cannot find name event details without IDs And so what we're looking for here is we're going to create the event, like, let's say in our database or something and so we're going to generate a new ID for it because usually you don't let the user give their own IDs to objects in your database, and we're taking in the host here as a user, which means we know the host ID from there

[00:06:59]
So we basically need all of the rest of the stuff that describes an event besides the ID and the host ID So is there a convenient way that we could make a new type, event details without IDs, by manipulating the types, the interfaces that we've already created Anybody remember a handy little Rosen suggests to use omit

[00:07:38]
Ah, there's omit How about omit How about our handy dandy built-in utility types So now we could declare this right above here, but let's put it up with our types just so we can remember what's going on Is there a walkthrough I can follow in the chat So an option to just omit the ID itself would be omit angle bracket, event, comma

[00:08:07]
Oh, sorry So TypeScript is struggling to autocomplete here because I'm just typing omit angle brackets, but we probably want something to the left of this Event Oh, sorry, interface So we can make it an interface The thing is with these utility types, what we're going to end up with is something that's a little bit like, let me go back to our playground

[00:08:49]
Alright, so let's kind of revisit our playground where we had been looking at this example of like extending these different interfaces, and so we said that interfaces are useful for object-shaped types where we want to be able to kind of compose them with this extends keyword in a sort of object-oriented inheritance-y kind of vibe

[00:09:18]
And these utility types, they are going to be very handy to drop in in places where we would otherwise just say the name of a type, like number or human or user, or whatever it is And so here, if I were to try to declare like interface usernameless equals omit human username, TypeScript's going to complain about a syntax error because this is not how we declare interfaces

[00:10:01]
They have a different syntax where it looks a lot more like a kind of like a function declaration or class or something like that So we don't get to have that equal sign to sort of assign the alias like that We would be using interfaces if we want to add or change the properties of an existing interface We might want to extend that interface, or if we want to make an object type, a new object type that we think other people or other of ourselves later in the future are going to want to extend

[00:10:39]
But so here, if we want to be able to kind of refer to this omitted type as its own type name, what we'd want to do is declare an alias with the type keyword, because then we can use that equals and essentially just sort of grab that type as like a, almost like we'd grab a value into a variable So in this case, let's use that type syntax

[00:11:13]
But the overall idea that we're working on this, omit, is spot on So we said if we type event details without IDs as omit, and then it was open angle brackets, and then can we go back to the helpful suggestion It was omit, open angle brackets, and then the base type here is going to be our event type, right And then I'm going to put a comma, and TypeScript is helping me here

[00:11:44]
We're not going to worry too much about what that means, but we know that this omit takes in two things, two type parameters So the next thing that I'm going to pass in is the keys of this event interface that I want not to be there And that would be, can somebody help me out ID Exactly, ID And then Rosen was using the union to add the host ID and ID

[00:12:30]
Exactly OK, so now if we sort of save that, save and let's see if we finally get our tests to run, yay, hey hey I no longer get my TypeScript error I no longer see red squigglies popping out at me, and the tests appear to be passing So success is ours Now, really quickly, just because you're going to see it a lot in TypeScript, I very hand-wavily said like let's ignore that, ignore that, ignore me doing this, ignore me doing this, while we were typing this out

[00:13:16]
TypeScript was helpfully giving me some hints here, like that, oh, we require two type arguments, and if I start typing this out, event, it said, OK, omit takes, first of all, its type parameter T, that's going to be the type that we want to omit stuff from, and then it takes a type that has a really weird representation here, K extends keyof any

[00:13:46]
Any is just because it doesn't know yet, because I don't have the right syntax yet It doesn't know yet that we're talking about the event type, but what this K extends keyof does is essentially saying the thing that goes to the right of the comma there, it has to be a subset of the keys that I know about in that type

[00:14:17]
And that is, there's an operator that we're not going to use a lot, but you'll see a lot in kind of type hints and things like that called keyof, which is a way to extract the type that is the union of all of the keys of a particular type So that's kind of what we're leveraging without knowing too much about it yet, when we do ID or host ID, what we have now is this type, which is a union type of these actual literal things here, these keys that is an extension of, it like matches the type keyof event, which would be all of the possible keys

[00:15:11]
So it's sort of like doing object.keys on a JavaScript object It's like you could kind of think of it like that So again, not something we're going to, it's a little bit more than first steps to get into how all of these super generic types are typed this way or are declared that way with words like keyof, typeof, blah blah, and just know that it exists and that you can read all about it on the TypeScript docs site

[00:15:43]
OK, but fabulous So now we've got our tests passing, we've got our, hopefully compiler happy Let's just double check with an npm run compile, and indeed, it ran, it outputted, it emitted, it conquered And it did not yell at me, so that's a win in my book Excellent work, everyone.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now