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

Mike demonstrates intersection types in TypeScript which can be described using the & (ampersand) operator and walks through an example of adding extra data to a Date object. A student's question regarding clarification on the difference between union and intersection types is also covered in this segment.

Get Unlimited Access Now

Transcript from the "Intersection Types" Lesson

>> Great, so those are union types. Let's talk about intersection types, and as we get into intersection types, I should be clear that you're going to find union types far more often. And I want you to think about why that might be, well, we'll leave that as a mystery for now.

[00:00:17] Intersection types are substantially more rare. And conceptually, what an intersection type is, just to remind you, it is an END operator. And this is where in terms of the values allowed, if we go back up to the top here, we're talking about only the overlap between these two sets of things.

[00:00:43] Let's use an example here, and let's imagine a case where we wanted an instrumented promise. And by that I mean a promise that sort of measures the time at which an async operation began, and then a time at which things finished. Maybe you want to print this to the console or fire some sort of tracking event, so you can understand how your code's performing.

[00:01:10] In any case, it could look something like this. Well, sorry, I described a use case here and actually changed my mind and made it a similar use case. Let me describe what this use case does. Just cuz the promised one turned out to be tricky, this is something I've actually used it for to be clear, this is something I can make a concise example around.

[00:01:34] So, what we're doing here is we have a date, and we want basically date to have a new property on it that's called end. Now we're not changing all dates by reopening the prototype and tacking on a new function, we just want a date with extras, a date with some extra stuff on it.

[00:01:55] So this is what this could look like. So we've got makeWeek, and it'll use today as the start date, it'll add a week to today's date in order to establish the end. And I'm using this spread operator to basically get everything that's on date, or everything that's on start, rather, and then tack on the other day at the end of the week to the end.

[00:02:23] The type I get back is everything that you know and love about date, and in addition to that, an end property where you can find another date. I'm just gonna open this in the playground. So we've got all of this stuff, the regular date API, and there's the end, and there's the other date.

[00:02:46] So it's sort of like mashing these two things together, right? That's what this end operator does. It's almost like a merging together of two types. This being one and this being the other.
>> Doesn't this look more like a union than an intersection? Because when you say, this way it doesn't have all the properties of the data option.

>> So if you look at the behavior that's available to you, it like feels like the labels for these types are kind of reversed, right? But if you think about these in terms of the values that you're allowed to have, that's where this makes sense. So let's go back up to our diagram at the top, let's say that we have a set of a bunch of different values here.

[00:03:41] On the left, instead of fruit, we have all things that are dates. And on the right, we have all things that have an end property whose value is a date. The only thing that we're happy with here, the only thing that matches our type with that intersection type operator, the end, it would be things that meet both categories.

[00:04:06] So, depending on how you look at it, you could see at one of two ways. If you're thinking about this in terms of the the set theory, meaning, I have a variable of this type, what values is it allowed to hold? Then it's this slice in the middle, it's the intersection.

[00:04:24] But if you're thinking about it in terms of the resultant object, what can I do with it? Well, that's where you see everything. If we changed our mental model to like, on the left, we've got things that can be done on date, and on the right we've got things that can be done on this object with an end property, now we can do everything, right?

[00:04:46] It's the whole thing. That is not what this kind of type derives its name from. It's not about what you can do with it, it's about what types of values may it hold. But I feel your pain in that, I get these things mixed up a lot, because it's tempting to think of it in terms of what may be done on this thing.

[00:05:14] But where they get their names has to do with which set of values are allowable to be type equivalent to this thing. Does that make sense? It's really tricky, I used to teach this and say, look, I want you to push intersection and union those words, push them out the door and just remember end and or.

[00:05:35] Cuz we know we've got the two symbols, they match up with the way we use them in JavaScript conditionals, that level of understanding will take you a long way. But in terms of the way we think about these sets, it's really mostly about what can this value hold, and it's only the things that are both.

[00:05:54] And as a result, you get everything that's available on either type, right? Hopefully, that makes sense, I'm always looking for better ways to explain this to folks. But it's a common dissonance that people experience when they learn TypeScript. All right, so I am stating, I'm postulating that there's a 50 to 1 ratio or more of when you'll see there we go, I'm searching them already.

[00:06:34] A 50 to 1 ratio, when you'll see the or types versus the end types. And as you think about why this might be, consider control flow. So, we can have functions that branch, right? You have a condition and in one case you do one thing and the other case you do another thing.

[00:06:56] The return type of the function ends up being path A or path B. So a lot of these or types originate from things that look kind of like this. Right? As a result, we get this or, this will happen a lot in your code. Branching is something that happens a lot.

[00:07:27] Control flow happens a lot, it's a very, very common phenomenon. This sort of merging of two things together, much less common, so that's why you're gonna see this or thing far more often. It's because control flow results in many possibilities, depending on what the inputs are, and thus you get the or, or union type out.

[00:07:59] And that's it, that's the end and the or. The devil's in the details here, and when used in conjunction with other things gets more complicated, but you can just think of it as end and or. With that, it's about time for us to talk about interfaces and type aliases.