No intersection types are one thing used more often however is a natural feature and that would be type
guards.
A feature we actually already used a bit let's use combined BBL here.
It's a union type where we even have a string or a number and type cards help us with union types because
whilst it is nice to have that flexibility often you need to know which exact type you are getting now
at runtime.
Let's say here we have our add function where I get a number which needs to be of type combined ABL.
So a string or a number and therefore I'll actually name it a year and then I got another argument which
also needs to be combined.
So a number or a string and then it will return A plus B.
Now we saw in the past that this does not work.
Instead we now need to check if type of A is equal to string for example or type of B is equal to string.
And if that is the case we return a two string plus B to string.
So we concatenate these two strings.
Otherwise if we don't make it into this if statement v return A plus B like this because now typescript
knows a and b have to be numbers here because if at least one of them would not be a number we would
be in here.
Now this year is called a Type guard because it allows us to utilize the flexibility union types gives
us and still ensure that our code runs correctly at runtime because often you have functions that work
with two or three different types and therefore a union type is perfect.
But what exactly you do with the values then does depend on the type.
Like here where we even concatenate or we add mathematically.
Now this is a type card using type of you can all the right other kinds of type cards.
And for that let me come back to my admin and employee types.
I got up there where I got privileges on the admin and start date on the employee.
Now we have the elevated employee which combines both.
Now I'll also create another type here.
That's the unknown employee.
This is ever just an employee or an admin.
So we have a union type using my to custom object types so I know an employee is either off the to now
we might have a function print employee information where I need to pass in an employee and that should
be of type unknown employee.
Now here I want to console log various pieces of information about the employee for example the name
from EMP dog name which will work without issues because both types of employees have a name property
but then I also want to console log the privileges by accessing EMP dot privilege.
And here I already get problems in the auto completion because typescript can't confirm that this always
exists on the argument because the unknown employee might be a normal employee which does not have a
privileged property only the admin asked it.
So now we need a type card here.
The problem just is with type of will not win anything if we check the type of employee debt will just
be object at runtime.
That doesn't tell us whether it has this property or not though.
Hence if I move the code in the safe check typescript is not happier than before because an object is
well just an object doesn't tell us anything about the properties we can check if it's off type employee
because dad is not a type.
Javascript knows and keep in mind that this check runs at runtime and uses javascript so we can only
compare the type type of gets us with the types javascript knows and that would be object string number
and boolean and so on and our custom type is not part of it that only exists in typescript world not
in the comp. javascript world so therefore does also does not work.
Now here a work around is to use a different if check.
We know we want to access privileges so we could check if employee privilege is a thing.
The problem Justice types typescript doesn't allow us to X this property at all.
Not even to check it like this but there is a different way for us to check it.
We can use the N keyword that's built into javascript we can check if privilege is now written as a
string is in m.
This is javascript code that allows to check if this exists as a property on employee and if that's
the case typescript a text is check here and therefore allows us to access this property inside of this
if check here and we can repeat that for the start date and therefore check if start date is a property
here and we can therefore also output this in this if check.
So now with that if we call print employee information and we pass in that one employee we created you
1
you will see that this compiles without errors and indeed outputs the privileges.
And while also here to date I should just also say start date here of course.
But with that it gives us the output we would expect.
And on the other end if we pass in an employee which does not have all these fields for example if we
create one on the fly which only has a start date but no privileges then does all the works and compiled
without errors and we simply don't print anything about the privileges because of this.
If check we have in their when working with classes you can also use a type of type guard and that would
be the instance of type guard let's say down there.
We have a class car that has a drive method where adjusts a console log driving and we have another
class truck which also has a drive method where we maybe you say driving a truck but we do have to say
method name and where we all have a load cargo method where we have an amount which is a number and
then here I'm just having some dummy code where I say loading cargo plus amount something like that
amount something like that so that we have two classes which of course have some similarity.
The drive method but also have a difference.
Now again we can create a union type here vehicle which is either a car or a truck.
And now let's say we create a new vehicle.
We won which is a new car and a number one B2 which is a new truck.
Now I have a function use vehicle which just expects to get a vehicle which should be of type vehicle.
So what should be of this union type so here we get a vehicle.
And now let's say our goal here is to do everything we can do with vehicles drive and load cargo.
So of course we can call vehicle drives because that always exists.
But for vehicle load cargo we have a problem because only a truck has that a car doesn't have it.
So this won't work.
Now we can of course again check if load cargo is in vehicle and if that is the case we can use it at
least if I fix that typo here.
So we now save that and we then call use vehicle and pass in the one and then we call it again with
V2 and I save all of that.
It compiles and it works.
Now that is one way of doing it and I'll shoot it this way which might be a bit more elegant because
it also eliminates the risk of you Miss typing in this property string here is that you use instance
off we can check if vehicle is an instance of truck if that's the case we know it will have a load cargo
method an instance of is a normal operator built into vanilla javascript.
So this is no typescript code just like type of this is part of JavaScript and it executes at runtime
javascript doesn't know the truck type but it knows constructor functions and classes in the end are
just translated to constructor functions and typescript is then able to find out if Weigl was created
based on the truck constructor function so since classes are compiled to something javascript understands
constructor functions it is able to use that if we would be using a interface here instead of a class
and therefore of course we couldn't have to implementation in here but would do that when we create
object with the object literal notation then we could not use instance of because interfaces as you
learn are not compile to any javascript code and therefore we can't use them at runtime for a class
as we can do that because javascript supports classes in constructor functions and with instance off
you can then find out if some object is based on that class and we know if it is then it will have a
load cargo function.
So these are type guards in the end type guards is just a term that describes the idea or approach of
checking if a certain property or method exists before you try to use it or if you can do something
with the type before you try to use it for objects that can be done with instance of or with in for
other types you can use type off and therefore we now have all the flexibility to use the flexibility
union types give you and still write code that then does one thing or the other based on the exact type
you're getting at runtime.