- Now this video is going to be a little bit longer
'cause we need to cover everything you need to know
about how you type a function.
Let's say we just have a really simple function
that's called printName.
It's gonna take in a name
and then it's just gonna console.log that name out.
Now immediately by defining this function as is,
we're gonna get some errors because we need to define types
for what the actual parameters are
that you pass this function.
For example, this name variable doesn't have a type.
It's implicitly set to any
which we do not allow in our config.
So to type a parameter inside of a function
is just like with a variable,
you put a colon followed by the type of that variable.
In our case, our name is a string
so we can print it out just like that.
That's how we type this function,
it's pretty straightforward.
If we add another parameter,
for example, we have name2 on here,
we just need to separate it by a comma, just like normal,
and then we can put the type
and now we can print out both of these names
and you can see our code is working just fine.
So if you wanna type a parameter, just put a colon
followed by the actual type of that parameter,
relatively straightforward.
Let's create a new function though
so we can talk about how you type
the return type of a function.
This is gonna take a and b, which are both gonna be numbers,
so we're just gonna type this as is, just like that.
And then inside of here, we're just gonna return a + b.
So now let's just say const_c is equal to sum (1, 2)
Now if we hover over c you can see TypeScript
somehow knows that c is a number.
We'd never actually defined
a return type for our sum function,
but since TypeScript does inference, it actually knows
that the return type of sum is going to be a number
'cause when you add one number to another number
it returns a number.
And if we hover over our function, we can actually see that
'cause here you can see we have our function being defined
and you can see the return type
at the very end of the parentheses here.
That's actually how we manually define our own return type.
So if I wanted to explicitly tell
the return type of my sum function,
I would just put a colon followed by
what I want the return type to be.
In our case, it is a return type of number
and now that's going to work just fine.
Now when you're dealing with return types and functions,
I highly recommend that you never actually explicitly
define the type of the return type
unless you absolutely need to.
But in 99.9% of scenarios,
the inferred type is going to be plenty good for you
and it's going to be even better
because now if, for example,
I would've changed my return here to be a string,
my code is just gonna be smart enough to know that
now c is going to be a string,
I don't have to manually come in here
and change this to a string from a number,
it's just smart enough to infer all of that for me.
Essentially in TypeScript
when you can infer something and it works,
almost always go with the inference route
because it's just going to be easier to maintain
and it's gonna be more flexible for future changes.
Now another thing I want to talk about
when it comes to functions
is how you deal with passing objects to a function.
Let's say here we're gonna change this function
to be printName, actually we'll just say printPerson.
There we go and this is gonna take in a person object
and it's just gonna console out log(person.name).
Now in our case, we need to define a type for this person,
we can do this in line or by creating another type object.
We're just gonna do it in line real quick
and what I can do is I can say here we have a name
which is a string,
that's the only thing I care about on this person object.
Now if I were to just call print person down here,
we can come in and we can pass it a name, for example, Kyle
and now you can see we have no errors,
everything's working fine
and it knows that this name is a string.
Now there's some interesting things about objects though
that you need to understand.
If I were to try to pass a property
that's not inside of this type right here,
I'm going to get an O error.
So for example, if I say age is 28,
you can see I'm getting an error 'cause it's like,
"Hey, you're passing along this age property,
but this age property doesn't actually exist
on this person object right here."
And this is a really nice warning
because when you're manually typing in your actual object
and passing it to a function,
so it's not an object from a variable from other sources,
it's just an object that you manually type in right here,
Typescript is gonna warn you
if you accidentally add parameters
that are not meant to be there.
And that's because maybe
I accidentally typed name wrong here,
for example, I did like this
and it would actually give me that warning letting me know,
"Hey this property doesn't exist,
most likely it's 'cause you typed something wrong."
But if I were to change this
and I extract this out into a variable,
for example, I just create a variable called person
and I set it equal to this
and I pass this person along to here,
you're gonna notice we no longer get those same errors.
So this is kind of interesting
because I'm passing the exact same object
to this printPerson function
and in this scenario I'm getting no errors
even though I'm passing along additional information
that's not included in my person type.
While when I actually hard code my object into here,
you notice I get this error.
This is actually a really nice feature of TypeScript.
The reason that you don't get an error
in this specific scenario
is because this person object could have other properties
on it that it just doesn't really matter
if those get passed down or not
because TypeScript is a little bit different
than like a super strict type language
that you may have used in the past.
TypeScript only looks at the structure
of your objects to determine if they are the correct type.
So if the object we're passing along
has a name with a string, it's going to be fine.
It doesn't matter
if it has a million other properties defined on it
as long as it has a name which is a string,
that is the only thing that TypeScript cares about.
So in that case, they are essentially the same type
for this printPerson function.
Now the reason it doesn't work
when you hard code this value in there though
is because TypeScript knows
that you're explicitly passing in this age property,
it's not coming from another object
somewhere else that may have
these properties added on for some other reason.
You're explicitly telling the code,
I want to pass an age property in here and TypeScript knows
that this is probably not something you want to do.
Now technically the actual TypeScript code itself,
the difference between this and this
where you actually passed on the person like that,
these are the exact same things of code
for actual like JavaScript running purposes,
they'll do the exact same thing.
The reason, again, TypeScript throws this error here
is because you're explicitly telling it
that you're trying to pass down an age,
but this doesn't deal with ages at all.
And this is just helping you
in case you accidentally make a typo.
So for example in that same scenario,
if I were to like spell name incorrectly here
it essentially is letting me know like,
"Hey, you've actually probably spelled something wrong"
and when you're trying to pass down a property
that doesn't actually exist,
it's really just there to help you as a developer
not so much to like guarantee your code is correct.
And that's kind of a thing with TypeScript overall.
A lot of times you can write correct JavaScript code,
but TypeScript will still throw errors
because it's saying,
"Hey, you probably did something wrong
that you didn't mean to do."
So just know the differences between these two,
since TypeScript is structural based
that means if you write code like this
it's going to work fine because it's all it cares
is that we have this name property.
But in specific scenarios
when you're passing down an explicit value
that has this like age, for example,
when we pass it down here,
it's just doing a simple extra check
just to make sure that your code is going to be working fine
and that you didn't accidentally
spell something incorrectly.
Other than that though, functions are relatively similar
to how you define variables.
You just create your parameter
and then follow it by a colon
and if we were to extract this into a type,
for example, we wanna define a person type,
that's really simple as well.
We would just say type person is equal to
paste down that person type, there we go.
And now you can see that that is working just fine
especially if we remove this age right here.