- The next two built-in types I wanna talk about
are complete opposite,
and they are the partial and the required type.
They just essentially allow you to create a type
that either makes everything optional,
or everything required.
For example, I have this todo type here
which has a title and a completed property.
And let's say that I have a form for creating a todo.
Obviously if I wanted those form inputs to be in a type,
they would all be optional,
because by default the form is completely blank.
So to create essentially an optional version of this todo,
I can create a brand new type,
and we'll just call this FormTodo.
And this is going to be equal to using our todo,
but we wanna wrap it in that partial type,
and we just pass in our todo,
and now it makes every single key
inside of this type optional.
If I hover over this, you can see title and completed
are now both optional.
And this is super simple, it only takes one generic,
so it makes the entire object optional.
Or if we were to use required here instead,
and these started out as optional for example,
you can now see the FormTodo
has everything set to required by default,
and it removes all the optional things that you can do.
So it just does it on the entire object,
every single thing inside of it.
And if I were to like, do some nesting, for example,
I had an address with a street
which is going to be a string here.
And let's just make these different things optional as well.
When I hover over this,
you can see that it makes the address required,
but it doesn't do deep nesting.
So this street is still optional 'cause it's nested.
It only does the top level keys.
Now if I wanted to make only certain keys required
and not other keys.
Like I wanna make it so the title's required,
but the address can stay as normal,
well now I need to combine together
the pick and omit keys with required.
So for example, here I want to only make it
so the address is required or I'm sorry,
the title is required.
So from my todo, I can pick specifically
just the title property.
Now by doing that, if I close this off,
I can look here and I can say I get a form todo
that just has a required title, super straightforward.
But I wanna get all the rest of the properties here as well.
So I can use an intersection to combine this together
with my original todo.
And now if I hover over this, you can see
it's combining these two different things together.
But that's going to be overriding some stuff
'cause it's gonna be getting the title from here as well.
So I want to omit the title from this one.
And by doing this I'm essentially saying, okay,
pick just the title and make that required.
Then combine that together with everything else
minus the title to give me what I had before.
And now if we try to create something
that has that FormTodo type, just like that,
you'll see I can put a completed variable in here,
so we'll say that is going to be true,
and I can pass in a title which is whatever,
and you can see our address is still optional,
which is great, but our title is required,
'cause if I remove that, I get an error because title
is missing and it is required.
And that's because of how I set this up right here.
So it's very common that you're going to be seeing
required and partial together
with the pick and omit properties to make
just certain things required
and just certain things not required.
It's so common that you may actually
write your own helper functions that essentially
do this line of code for you inside of like, your own type
where you can have like,
PickRequired or RequiredPick or something like that.
You can make your own type to do that if you really want.
Now the one nice thing about required,
if we just remove this back to what we had before
and we actually get rid of those omit
and notice it also still works just fine.
And that's because a required property
is going to overwrite an optional property
when you're combining together two types like this,
but it will not work as well for partial.
So for example, by default our title is required,
and now we want to make that title optional.
You can see here I need to make sure I omit the title
from the second one because required properties
always override non-required properties.
Now you can see my title is optional in this,
while when I wasn't doing this omit,
the required title was overriding,
so now you can see that title is required.
That's why I'm getting this error down here.
So if I wanted to write out a fancy type to do this for me,
I'm gonna do it for required, for example.
What I could do is I could say
that we wanted to have a required pick.
And this required pick is going to be a generic type
that is going to take in whatever the thing is
that I wanna check, that's just the default,
T is what I'm going to call this.
That's the object I'm going to be checking
or the type I'm gonna be checking.
And then I want to get all the keys from that.
So I can say that I want to get K,
which is gonna be one of our keys,
you can call it key if you want.
And that's going to extend the key of T just like that.
So this is very similar to how pick normally works.
This is the exact signature pick uses.
Essentially it's saying we have a type,
and then we have any of the keys from that type
as the required pick section.
Then I need to set that to an actual type.
So we can use required here.
We want to require a specific type,
but we only wanna pick the specific keys from here
that are in the section we called Key.
So we'll call that Key, just like that.
There we go.
And now we have a required pick.
So if I were to just extract this,
bring my code back to where we had our actual todo type.
And now what I can do down here is I can say, you know what,
I wanna make our title required.
So we'll make it optional up here.
And then down here, or actually, sorry,
I'm gonna put this type in so we can use it.
Now I'm just gonna call RequiredPick,
I'm gonna pass in my todo,
I'm gonna pass in the thing we want to check,
which is our title.
Close that off, and now you can see,
it's not quite working 'cause we need to make sure we also
add in the union or sorry,
the intersection of our type as well.
Now if we give that a quick save
and we hover over our todo,
you can see property title is missing.
So it's very common for you to write a required pick
that looks like this.
And if I wanted to do the same exact thing for partial,
I could say PartialPick.
And what that's going to do
is it's just gonna swap this out for partial,
and we need to make sure on our second one,
we emit the exact same properties from our object
right here, and we called this Key.
There we go.
But now if I wanted to make this a partial pick
where the title starts out required
and now becomes optional,
you can see that that is working just fine.
Now to real quickly recap what these lines of code
are doing essentially, our required pick,
we're saying that we have a specific type,
in our case the todo type, it doesn't matter,
just some type, we're going to be
essentially requiring certain keys from.
In order to get the keys,
we're saying that this second property
can be anything by default.
If we just said key, it could literally be anything.
But by extending the keys of T, we're saying, okay,
this must be one of the keys in our type T.
In our todo case, that means it has to be title,
completed or address.
You can see here I actually get autocomplete
for address, completed and title, just like I would expect.
Then what I'm doing is I'm saying, okay,
we're going to require picking just from that type
all of those keys and we're gonna be intersecting it
with the initial type just to make sure
we get all the other stuff from before as well.
So it's taking all the stuff that I'm not picking,
leaving it the same, and then the stuff I am picking,
it's making required.
It's just like the code we had before
but this code is a little bit more condensed
because we're just using T here
instead of the full todo name.