More mobx-state-tree Types: map, literal, union, and enumeration

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 3 years ago

It is time to give our wishlist app some more depth. In this lesson, we will introduce the concept of groups and users. So that we can manage multiple users inside a group that can have a wishlist. Also, we will take a quick look at powerful features like union types and type discrimination.

In this lesson you will learn:

  • Using the type map to store data by key
  • Using literals to create single value types
  • Combining literals and unions to do type discrimination
  • Using Quokka as scratchpad for quick coding experiments
  • Using enumerations
  • Enumerations are just sugar for a union of literals

Instructor: [00:00] So far, this is actually a pretty useless application, because it captures a wish list, but only one, my own. Of course, something like Santa Claus or Christmas, you should celebrate with family or friends. What we need is to introduce groups -- groups of persons, where each has their own wish list, so let's improve our model a little bit.

[00:23] We introduce a new models file, groups.js. Again, we ware going to define some types. The first one is a user [inaudible] . User has some identifier, which now you're going to say is string.

[00:37] He has a name, also a string, and he has a gender. You might be tempting to express this as a string, as well. Actually a gender should something be like male or female.

[00:50] We want to have, literally, these values. That's where literals come in. We want, literally, an M or we want, literally, an F. Expressing a type as the choice between either one type or another is, in type systems, typically called a union. We can take the union of these two types, and then we have the gender expressed. Now the gender should be either an M or F.

[01:19] I'm going to demonstrate it very quickly by using a really cool [inaudible] plug-in called Quokka. With Quokka, you can quickly create a scratch pad with some java script or typescript and run it. If I now say user.create, some ID, some name, and then the gender -- I put a weird character -- it will throw an exception. It says, "Z is not assignable to type F or M." If I do it like this, it's all OK.

[01:50] Actually, literals are very powerful types. They seem a little bit weird at first to have a type of a single value, but they can also be used to do type discrimination, for example. Let's say that we didn't allow users like this, but we introduced some different types. We have women, where the gender is always a literal F, and we have also men, where the gender is always a literal M.

[02:18] Now, I can define humans as the union, because union can combine any types, of a man and a woman. Now, if I instantiate this human, we can simply check that now somebody is a man and he is not a woman. What happens here is that when the human was created, the types of union try to find the best matching type for this man or woman.

[02:48] Based on this literal, the gender M, it knows that it could never be a woman, but has to be a man, because that's where the type matches the value I've got. These things are all supported out of the books in mobx-safe-tree. We have unions and literals, and we can make very powerful type space on them.

[03:11] Back to our group. This is quite a common pattern where we have just the union of some literal values. There's a shorthand notation for that, and it's called enumeration. Enumeration, we call it gender, and then, again, have the literal values, male or female.

[03:30] Of course, our users also have a wish list, so let's import our wish list definition. We simply say wish list is an optional wish list. If it's not defined, we just start with an empty list. That defines our user.

[03:48] Now we can define a group, and we can say a group is a collection of users. In this case, I'm going to use a map for that. We could also use an array, but you've seen that one already.

[04:04] Now we've restructured the model of our application and we should update the UI for that. Our wish list is no longer the root of our state, but our group is now the root of our state. We'll update our index file, and we'll preferably create a wish list or load it on a wish list.

[04:22] We now load a group. To keep things simple, I prepared some hard-coded data with some initial users based on the Simpsons family, so we'll be passing a group into the root component. We should update our UI accordingly so that we can select a single user, add, see or edit his wish list.

[04:46] The app component now gets a little bit of state -- selected user, storing the ID of the currently selected user. We render a select books, which shows all the users in our group. Whenever we select one, we update the state of this components to reflect the new selection. Instead of passing the root wish list, we now pass the wish list of the selected user to the wish list view component.

[05:22] Now we have restructured UI, we can select users. With that, we are ready for the next lessons. In this lesson, we introduced some of the more fancy types, like literals, enumerations, unions, and maps.

Alan Plum
Alan Plum
~ 3 years ago

This is probably not the most politically appropriate example to use for unions, to be perfectly honest.