Two Techniques for Mapping a Discriminated Union to an Object
As mentioned, there are two possible solutions to this exercise.
Solution 1: Creating a Union
One way to solve this problem is based on creating a union of all of the possible route
values, which is the discriminator.
Here's what this this solution looks like:
type RoutesObject = {
Transcript
0:00 Let's take a look at this first solution here, where we have the route, and what we're doing is we are saying for R in route, route, we're taking this as the discriminator. We then say extract route, route, route, route, search. Let's work out what's happening here.
0:19 If we just take this and we just take a string there, then what we end up with is we've got the discriminator and we're turning this into an object where the keys aren't the discriminator. That's good. That's what we want to do.
0:33 We end up with R, which is this route thing here, and what we want to do then is we basically want to say type extracted equals, we have access to about, and admin, and admin users, but we don't have access to the search within this iterator. We somehow need to grab the search.
0:53 What we can do is extract and then say route, and then route is going to be, let's say, about one fact. Let's do the first one, and then we have access to extracted element there, so we have access to the search.
1:08 We can grab this just by using an index type, which is the search here, so we end up with the correct search. That means if we change this to admin/users, then we end up with the correct thing too. This is admin/users just has this, if we have id number, then we end up with the correct thing here too.
1:28 What that means then is that we're basically just in-lining this and instead of this, we have an R there. That means we do end up with the correct solution, but it's maybe a little bit too verbose here. There is an easier way we can do this, which is here, this looks just beautiful, doesn't it?
1:51 We actually instead of the R route being the thing we're iterating over -- if you notice in here, we're iterating over R route -- we actually iterate over route itself. R in this particular case actually represents the entire object, and what we end up with then is we can just access R search.
2:14 We don't need to do any of the extraction stuff. Our search actually represents the pieces that are in here. I can have id number in here if I want to, and that will make its way into this too, which is extremely neat. Then we just take that R and we key remap it to use the route as the key.
2:33 This is a delicious way to extract this and make it all work, and it means that you can actually iterate over each individual element of the discriminated union and then just pull out the parts you need.
2:46 If I were to just remove this actually, we get a really interesting error, which makes you feel like this isn't possible, because actually this, it's not assignable to string, or number, or symbol, because inside here, you can't put in any random stuff here, let's say, or string array.
3:04 Each of these numbers or each of these values are not assignable to the correct type. String, or number, or symbol, those are the only things that you can use as a key in TypeScript, but actually, if you just have it here and then remap it, so R route, then it lets you do it.
3:21 This is a fascinating little way to manipulate objects or manipulate discriminated unions into new objects.