TypeScript Fundamentals

Challenge 3: Solution

Check out a free preview of the full TypeScript Fundamentals course:
The "Challenge 3: Solution" Lesson is part of the full, TypeScript Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Mike walks through the solution to Challenge 3.

Get Unlimited Access Now

Transcript from the "Challenge 3: Solution" Lesson

[00:00:00]
>> Mike North: We're going to go through the solution to the third exercise where we're making a card dealer with TypeScript. And I've just copied the hints at what the structure of this class should look like from the slides, so that's what were seeing here in the comments. So the first thing we wanna do is collapse this since I don't need this shuffle array quite yet.

[00:00:24] So, I wanna create enums for suit and number.
>> Mike North: And these are alphabetical, so it would be Club, Diamond, Heart, Spade. Or, we'll do it like this, Spades, Clubs. And then we've got enum CardNumber.
>> Mike North: We do Ace, Two, Three, Four, Five, Six.
>> Mike North: Jack, Queen, King. So these are sort of, they belong as members of each other.

[00:01:12] This is a common example to use when working enums cuz there's a fixed size set. And we can represent these as numbers but it's more convenient for us to represent them as words, right? So we could represent a card as something that is more human readable than say, zero, comma, four.

[00:01:33] And speaking of a card,
>> Mike North: We can represent it like this.
>> Mike North: So if I wanted to have an object of type card, I could do something like this.
>> Mike North: Sorry.
>> Mike North: Something like that. So, that is easier to read than what the value of it really is.

[00:02:09]
>> Mike North: Which is,
>> Mike North: There it is, 06, right, so that's what this really is, seven of clubs, it is nice to be able to refer to this, in our code in a more semantic way. So, now that we got that straightened out we can define some of these functions.

[00:02:39]
>> Mike North: So I have dealhand,
>> Mike North: And that's gonna be a member function that'll take in a number.
>> Mike North: And it will return an array of cards.
>> Mike North: And we'll just leave that there, getLength,
>> Mike North: Is gonna be another function that's gonna return a number. And right now I'm just thinking like we'll have,

[00:03:27]
>> Mike North: Something like this. So card() = a new array. And here we can just right away say,
>> Mike North: Something like that, so we've finished that right away.
>> Mike North: readCard, it's gonna take as an argument.
>> Mike North: A card,
>> Mike North: Like that, and it's gonna return a string.
>> Mike North: And that's basically it.

[00:04:05] So if we've done that, we will have, hopefully, we've done some way to pass our test. And lastly, I believe I was supposed to export these. And we can export enums, so these do turn into JavaScript as we were seeing. And we can export them like we would export anything else.

[00:04:23] So you could have a file in an app, like often times you wanna collect a couple different inumes and have them all in one place so there's a go to spot. Kinda like the way you treat, constants or collections of constants that are meant to go together. So let's run our tests,

[00:04:46]
>> Mike North: And see the state we're in. All right, five passed, eight failed. So we've got the correct number of members in the enums, that's good. We are exporting things as we should, that's good. And now it's time for us to kind of go through the main work at hand.

[00:05:09] So the first thing I need is, we obviously need to create our deck of cards.
>> Mike North: So we can create a constructor here that is going to just for fun I'm gonna say, set upDeck that's done function. So this.setupDeck.
>> Mike North: And we can have this be actually just for fun, just for a good code structure here.

[00:05:38] Why do we have that be out here?
>> Mike North: I did not solve it this way when I did my solutions that are already checked in there, but I like this. So we're gonna create deck, and this is gonna just be a pure function that exists outside the context of this class.

[00:05:56] Benefit here is we could unitest it by itself, and make sure that it's always creating what it's supposed to be creating. This is going to return an array of cards. It's not returning it yet, but you'll note that we got a complaint here, cuz by default, function's return type is void.

[00:06:20] And as soon as we add this information that our intent is to return an array of cards. Now this is happy, but we've basically pushed the work upstream, and it’s saying you said you’d return this, we need to go about doing that. I love that I’m getting all of this feedback as we go along, we kind of define the structure and we’re sort of moving errors up stream, up stream, up stream until we're done.

[00:06:44] This is fantastic and like in a language like Java, you've got all this indexing that's going on behind the scenes and it's kinda figuring things out. TypeScript is I think faster in terms of delivering this feedback to me almost immediately because it's able to analyze very small trunks of code.

[00:07:05] Really sticking within this file and do incremental work to evaluate like based on what I've just changed, how is the type constraint situation being satisfied. What's the new feedback to deliver to the developer. So for createDeck let's worry about that, actually we can do here we can say shuffleArray(this.icards), so we're good there.

[00:07:31] Note that we can shuffle an array of anything, we don't care the contents we are just moving stuff around, so this will operate on whatever we want, shuffles it in place, right. So now, if we create a deck we just want to iterate over the length of, we wanna iterate over these enums.

[00:07:50] So we could do it this way, for,
>> Mike North: s for suit, = 0, s is less than,
>> Mike North: We could do it this way,
>> Mike North: Suit.length.
>> Speaker 2: Because you need to do Object.keys here?
>> Mike North: What's that?
>> Speaker 2: Do you need to do Object.keys?
>> Mike North: Sorry, you're right.
>> Mike North: It's almost like I just ate a bunch of tacos, and I'm about to slip into a food coma.

[00:08:28] Suit.length okay and then I'm gonna do s+=1 so I'm gonna skip by 2s here.
>> Mike North: Essentially saving me the trouble of having to half it each time. I'm gonna have something similar in here another for loop where I'm going to start at,
>> Mike North: We'll call this n for number and this is gonna be Object.keys, actually I don't want this fancy code thing that it's doing right now.

[00:09:03]
>> Mike North: Let n is 0 I'll do the same things up here, more or less.
>> Mike North: n is less than the length of the cardNumber, enum.
>> Mike North: n++ okay, so now effectively I should be inside this n squared thing, and there's no way around the n squared in this situation.

[00:09:32] We should hit this 52 times, 13 times 4. So now, I want to create a Card array. So we could say, let cards =,
>> Mike North: And we'll pre-allocate 52 spots since we know we'll need them at the end. We'll return the cards so this is happy now, there are gonna be look no cards in this array, it's gonna be 52 undefineds.

[00:10:11] So it's our job now to go through and define it.
>> Mike North: Actually, it'll be easier if we do it this way, frankly.
>> Mike North: Just so we don't have to compute the index every time, we'll be resizing the array potentially, but no worries. So now, this card is going to be suit first, and then number.

[00:10:36] And we don't really need to hold the reference to it, so we can just say, cards.push that in, and we're good. So that should create our deck of cards. Let's test it out.
>> Mike North: Should see 52.
>> Mike North: And,
>> Mike North: It's unhappy with some of my other functions here.

[00:11:11] We can give it temporary stuff to return to stop from complaining.
>> Mike North: 104, there's something wrong here.
>> Mike North: There it is.
>> Mike North: 52, okay. And if we wanted to see the cards themselves we can just take a look here.
>> Mike North: So this looks about right.
>> Mike North: Actually, maybe not okay, we're doing something wrong here.

[00:11:59] So cuz of the way I've done this, we're gonna have to do like,
>> Mike North: That, cuz we're skipping by 2s. Anyhoo, now we've got it, so the thing to scan for here is the numbers in the left column never get above 3, 0, 1, 2, or 3. And the numbers in the right column go up to 12, 0 through 12.

[00:12:22] So in this case, we could have gone through the enum and seen the values of these enums. But we can actually just use the counter as well, which is what we happen to be using here. Okay, so now we've got our cards. And we can remove our little temporary fixes here, so we get back to our useful errors.

[00:12:42] And now we've got to deal a hand and we can do this by saying this.cards and then splice, splice is what we use to remove a chunk of element from an array. We're gonna start from a particular number and that will be this, we could do this.card's length but we already have a length property on this dealer, so I'm gonna use that.

[00:13:10] And maybe some other type of dealer like, would have six decks, the casino style dealing where they mix it all together for blackjack. And getLength()- number, so we're gonna pop starting from there and then delete number, oops, sorry, numCards, I'm reading this incorrectly.
>> Mike North: And the last argument here is optional that would be what we want to put back into the cards array and we're not gonna do anything there.

[00:13:42] So, we if we return this, oop.
>> Mike North: Now, we’ve satisfied that ask there. So, now we’re actually down to it looks like we still have a couple of edge cases that we haven’t handled. We should throw an error if I ask for too many cards, and throw an error if I ask for a negative number of cards.

[00:14:07] So that's pretty easy, there are just some runtime assertions there, so if (numCards > getLength()) then we can throw new Error.
>> Mike North: Anyone know why I'm using the arrow constructor here instead of just throwing a string?
>> Speaker 2: Cuz it keeps the stack.
>> Mike North: Very good.
>> Mike North: If we just throw a string, it does not keep the stack.

[00:14:45]
>> Mike North: So that's less than 0 we'll say, please give me YOUR cards.
>> Mike North: Okay, one test left, reading the card. So now, we have to use the way this enum works to get from, well we know the value of each of this members of the enum is, that's a number.

[00:15:12] We see that as we were logging those topples out, we have to get to the string.
>> Mike North: So in this case we can say, we're gonna return template literal and here. It's gonna basically this form so we've got the card here I made the claim that these structured assignment works really nice with this.

[00:15:33] Here's how that works.
>> Mike North: So if I hover over these types it turns out that the typing has worked in the other direction, right. Because I know what's on the right-hand of the assignment operator. Is there's a tuple of that form, the first thing is the suit, the second thing is the card number.

[00:15:56] Now on the left-hand side, these things that I'm destructuring out of it they get the correct types. So these are ready to go, ready to put into the respective enums.
>> Mike North: And it looks like what's going on? Let's see what we returned and said.
>> Speaker 3: They're reversed.
>> Mike North: The clubs of seven.

[00:16:32] The seven of clubs, okay so just to recap how this works, up top we have this really nice easy to understand collections of related values think of them like they're all members of a particular type, right. Things that fit into a category. We have type safety around these so if I try to reverse these even though their both integers this is not gonna make your tuple happy.

[00:17:03] So this is the benefit here, it's not just like constants if we were to use just const number equals whatever. We could reverse those around, we don't get the type safety. So this is its own type, even though when we log them out they all kinda boil down to the same thing.

[00:17:19] That's one of the main benefits of using enums here, that you're assured to not have the right value, but to belong to the correct collection. So then we looked at how we might like get the length, the number of members in a particular collection. We,
>> Mike North: Then used these enum values, which are numeric, to sort of get the human readable string out.

[00:17:48] So like we refer to these things by name and now we can log them out. Unlike variables like if you have var x equals something there's no way when you have this thing you're referring to in your program called x to print out the string x, right? So these things have a string value and a numeric value and both can be useful in a situation like this.

[00:18:15] So hopefully that's a good crash course in enum types.