This course has been updated! We now recommend you take the TypeScript Fundamentals, v3 course.
Transcript from the "Mapped & Conditional Types, & Type Queries" Lesson
>> Mike North: We're gonna take a look at some more advanced types. I know it seems like we've already been in advanced having gone through with a generics. But I want you to get a sense for what's possible as you learn more and more about how to design effective constraints with typescript.
>> Mike North: First we're gonna look at mapped types. And this involves using an interface as a way from getting to the interfaces keys to the types associated with those keys. So we had a function earlier in the workshop where we were trying to contact people by phone or email.
[00:00:56] And we used overloads, we use multiple functions signatures, in order to insure that email, one with email and phone, one with phone. This will require as new communications methods were added, will requires to add more signatures, right? One for each new, coupling of the first and the second parameter together.
[00:01:20] So we are going to use map type to accomplish similar thing.
>> Mike North: So here is a new function, it's called contact, it has a type parameter that must extend from a key of the above interface. Anyone have a hunch as to what the possible values of that could be?
>> Speaker 2: Email ,phone, fax
>> Mike North: Email, phone, fax, thank you. So email, phone, and fax, and then we're taking that type and this is what makes it a map type. We're passing that key into the interface, and we'll get the corresponding value associated with that key. So here these three will all work, but if I were to try to reverse things like use phone up here we're gonna get the same kinds of errors that we were getting with the function signatures.
[00:02:17] The first parameter and the second parameter must agree. But in my opinion, this is a little bit easier to maintain because for new communication methods we only need to add a sort of a new road to the interface. And what's more, we could use this, we could consume this type and do this mapping across many different things in our app.
[00:02:38] So if you have some concept like the different types of models that you can get from your API, and you want to refer to them by name, and then you can get that correct type back. You can have one source of truth where all of this is maintained and then everything else that consumes the map's type in this way.
[00:03:26] So I just think of this like objects. So as you said, the available keys here, a key of communication methods email, phone, or fax. We can even get all values by taking these keys and projecting the set of the three of them through the interface to get all of the possible values.
[00:03:55] HasEmail of HasPhoneNumber or fax, that is all three of these up here. So if you have anything that were you've got a or b, or c, and pass it through interface, you'll get the corresponding value of that key or value of the other key, or the value of the third key, right?
[00:04:42] So here we've got a value whose type is a promise that resolves to a number. And I can get the typeof what promise that resolve has like the type of this function here, I can kind of acquire that by using the type of operator in the context of a type alias.
[00:05:10] You could do the same thing like this.
>> Mike North: Well, I do it like let, but there you go. So this is called a type query cuz you're kind of querying for this values type.
>> Mike North: Conditional types this was added in types script 2.8 which is pretty recent. This is a tunnery operator for types.
[00:05:36] So we've got a generic here, you can only use them with generics.
>> Mike North: We're saying we want to basically grab the type of a promise, or let something pass straight through if it's not a promise. So this is like, give me the eventual value that this will turn into and if it's not a promise, that is the value itself.
[00:05:58] So we take in a type T, if T extends from Promise, extract out the type that the Promise resolves to, we use infer here. This is the only place you can use infer, but it let's you pluck out the type the Promise resolves to. So if T extends from Promise, return what it results to, otherwise, just let is sail straight through.
[00:06:25] And here, we can see that a is of type number. We're saying EventualType of Promise number. A number comes out cuz we're following we're in the truthy clause here. In b we can see that the number array kinda sails straight through, right? Cuz it's following this branch down here.