Check out a free preview of the full Making TypeScript Stick course:
The "Typed Data Store Exercise" Lesson is part of the full, Making TypeScript Stick course featured in this preview video. Here's what you'd learn in this lesson:

Students are instructed to build a data store with type errors that alert on miss-named methods in the class. If a new entity such as Comic is added, type errors should alert the absence of a clearComics, getAllComics, and getAllSongs method. There should be no externally-visible properties on an instance of DataStore beyond the required methods, the code and the test suite should type-check, and all pre-existing tests should pass.

Get Unlimited Access Now

Transcript from the "Typed Data Store Exercise" Lesson

[00:00:00]
>> So it's time for us to get hands on and to tackle our first challenge. And this is gonna involve some of the new language features that we just discussed. In particular, we're gonna see template literal types, we'll see some key remapping. And, should be a good opportunity for us to sort of kick the tires on these things if you haven't had a chance to use them in your project yet.

[00:00:26] So, here is the challenge. I want us to build a data store. So what I mean by this is just a class that holds records of particular types. And so let's say this is for a media library of some kind, so we have a movie and we have a song.

[00:00:47] And you can see like there's this base interface with an ID and then movies in addition to the ID they have a director, and songs in addition to an ID they have a property called singer. So they're a little bit different. But we want something that allows us to get a list of all the songs, all the movies.

[00:01:09] It allows us to clear those lists out, it allows us to get something by ID. So that's what data store is going to turn into. Now, to normally that would be a fairly straightforward ask maybe a little bit too easy of a problem. What I want us to do is solve this problem in a way where this type is kind of the source of truth for what we are managing.

[00:01:36] Meaning, if I were to add, let's say, painting to this list and add a new painting type up here. I would expect some type errors to show us, look, you're supposed to have this convention where you have these methods on a per resource basis and they should be named a particular way.

[00:01:57] I would want some sort of enforcement through the use of interfaces, right? That there is this contract and each type of entity this data store managers, it has to have the get the list of them. It has to have the clear the list thing, and it has to have get by ID, okay?

[00:02:14] So, here's an example of usage. We create our new data store, we can see we're able to add songs, add movies. We can get a song or get a movie by ID. We can get the list, get all and then we can clear the list. And you'll end up implementing these directly in your data store class.

[00:02:37] It is a trap to try to get too clever with this, try to make everything generic, maybe try some object defined property backflips to sort of programmatically build this kind of thing up. Don't go there, we're not looking for programmatic assembly of this data store. We're looking to have great type checking.

[00:03:01] That's the point here, great enforcement of this contract. So, here are some requirements. If you miss name a method on the class, meaning you deviate from this convention, you see here we've got get all songs, get all movies. But let's say instead of that method name, you said get songs, we should see a type error and it should be somewhere reasonably close to where that problem needs to be addressed.

[00:03:31] If we add a new type of media to our data entity map, in this case I think I said painting before a comic would also do. And make no other changes to your solution, you should see type errors that tell you hey, data store is supposed to have these methods on it.

[00:03:53] So this kind of change should light some things up and you should see, hey, we're supposed to have this convention, we need to implement some things here. Pro tip, just make sure there are no other externally visible properties on the data store because one of the test in the test suite checks for a set of method names.

[00:04:14] And that test will fail if you have extra stuff in there. Your coach it obviously passed the test suite and type-check. And I think that's it. So, in terms of how to set this up, here's some instructions. Clone the repo, enter it. Install Volta, if you haven't already, it's not mandatory, but it will rule out some potential problems you could run into.

[00:04:40] This is the complete instruction for setting up Volta on a POSIX compliant operating system like Mac OS or Linux. And the job of Volta is to make sure that you're using the same package manager and node versions that everyone else is using. So if you've used like nvm, this is a modern version of that.

[00:05:04] So then you're gonna install your dependencies, move to the directory in which this challenge exists. You should be able to run Yarn test. And then here is the file that you're going to be working with. So I'm gonna go through the steps right now in front of you so you can see what that looks like.

[00:05:23] If you run into trouble, here are hints. There links to concepts that are involved in this solution. I'm not trying to lead you directly toward the key idea here, but my solution involves these things. So if you're stuck, take a look at those. So with that, I'll show you where to go to start your problem.

[00:05:53] So I've just checked out the project, now I'm gonna run Yarn to make sure I've installed all my dependencies. And then the location of this challenge is in challenges data layer. So let's go there. And then in here you should be able to run Yarn test, you should see a bunch of tests fail.

[00:06:21] And in fact we do. Here's the code that you should be modifying, it's in source, index TS. And you shouldn't need to change any of this stuff up here. This is sort of just the court date entities. In fact, you shouldn't really need to change this much except to experiment with whether adding that comic media type works, right?

[00:06:47] Everything else you can just do within data store. Again, don't try to get too clever with making data store, generate over the data entity map. It's okay for us to hard code that aspect of things. That's not the point of what we're trying to do here.