- In the last video, we talked about the union type,
which is saying one thing must be something
or something else.
In this video, I wanna talk about the intersection type,
which is essentially the opposite,
where I'm saying something must be
both one type and another type at the exact same time.
It's essentially the way
for you to combine different types together
with an and-style syntax.
So let's take for example, I have a type here,
which is gonna be Person, and this Person has a name,
there's a string,
and we're gonna give it an age, which is a number.
That's working perfectly fine.
What if I also want to have some people that have IDs?
So I can say like Person with ID.
Well, that is my normal Person type,
but I also want to add an ID onto the end of this,
so what I can do is I can use the ampersand symbol.
This allows me to combine different types together.
Just like you use the pipe symbol for or,
use ampersand for and, and this is gonna be one ampersand,
similar to how you use two ampersands in JavaScript
to do an and,
in TypeScript, you just use one ampersand.
And now I can add a new type, which is gonna be an ID,
which in my case is going to be a string.
And now this type is combining together my Person and my ID.
So let's come down here and we'll create a Person.
And first, we're gonna give them the Person type,
so we're gonna see how this specifically works.
So we can say that this Person is gonna have a name,
which is Kyle,
and we're gonna give them an age, which is 28.
As you can see, we get no errors at all
because it only expects a name and an age.
If we change it to a Person with ID,
we're now going to get an error,
and that's essentially saying here, property ID is missing,
but it expects there to be an ID property
because we said it should have this ID property,
'cause we're saying it has to be a Person
and it has to be a type that has an ID of a string.
So by coming here and I give it an ID of just whatever,
it doesn't matter,
you can now see it, when I save,
I'm no longer getting any errors
because I'm specifically adding
that ID property to my Person,
and this is asking for them to have an ID.
So this is a really common modifier to use
when you essentially want to add things
to a type that already exists.
In this case, we're adding an ID to a Person type
that already exists
to make it more specific by adding more content to it.
Now, if you wanted to do this with interfaces,
you actually can do this,
but the syntax is quite a bit different.
So it doesn't matter if this is a type or an interface,
we'll just change it to an interface,
just so we can see everything as an interface.
There we go.
We have our Person interface.
Now if we wanted to use our Person with ID,
we would change this to an interface,
and what we would need to do to create this interface
is we instead would say that it needs to extend.
So we say it extends this Person,
and then we can actually define
what the actual add-on is going to be.
And if we wanted to extend multiple things,
I would just put them inside of here.
So let's say that we have another interface,
and this one is just gonna be Todo,
and it's just going to say complete, false,
or not false, boolean.
There we go.
Doesn't really matter what this is.
If I wanted to extend multiple things,
I would just put them both inside of this list right here.
And now I'm getting an error on my Person
'cause the complete property is missing.
So it's extending all of these different things,
and then this right here is the actual definition
for my interface,
similar to how this is the definition for the type.
And what I could do is I could just completely remove this.
If I just wanted to combine together two different things,
I could do that as well,
and this would just need to be empty brackets,
just like that.
And this essentially just combines together
my Person and my Todo.
Now going back to what we had before,
if I wanted to do this as types instead,
let's change all of these to be a type,
make this here an equal, this here an equal.
And again, it doesn't matter
if these first two are types or interfaces.
It doesn't make any difference for what we're doing.
And I'm gonna come down here,
and instead of doing an extend, I'm gonna do an equal,
separate this by an ampersand,
and then separate this by an ampersand.
So if you want to do multiple things,
and it together as an intersection,
you just do an ampersand between each and every one.
And now this Person with ID
needs to include all the properties of Person,
all the properties of Todo,
and all the properties of this custom ID object here.
Now, unlike a union type, though,
the ampersand intersection type
is not useful when it comes to primitive values.
So normally if we wanna do like a literal
where you say the status is going to be complete
or incomplete or something else,
that makes sense as a union,
but as an intersection, that doesn't make sense,
'cause we can't have a type that is both a complete status
and an incomplete status and draft.
It can't be all three at the same time.
It has to be one of them.
That's why we use a union.
So you can never use a union with,
for example, like a primitive number type.
This will always give you a failure
because I cannot both be an object
and a number at the same time.
So if you're using primitives inside of your intersections,
that's obviously a red flag.
Don't do that, because it just doesn't work.
You can't have an object and a number at the same time.
They just don't work together.
And the same thing happens if I try to add a Person
that has the same property as something else.
So here my Person has a name and an age.
We'll get rid of this Todo for now
'cause we don't really need it,
and what I'm gonna do,
and then I'm gonna add a name property here as well.
I'm gonna say name here is going to be equal number,
just to give it a different type.
And now you're gonna notice I'm getting errors
because I can't have a name
that is both a number and a string at the exact same time.
That just doesn't work.
It's impossible.
You need to make sure
if you're using this ampersand intersection
that you don't have overlapping types
that have incompatible types,
'cause if you do,
it's going to give you an error no matter what you do
since it's impossible to have a name
that is both a number and a string at the same time.