React and TypeScript, v3

Advanced Zod Types

Steve Kinney
Temporal
React and TypeScript, v3

Lesson Description

The "Advanced Zod Types" Lesson is part of the full, React and TypeScript, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Steve introduces various advanced TypeScript concepts to the students, explaining how to manipulate types using Zod schemas. He demonstrates how to chain optional types, validate data structures, and coerce values to ensure they match the expected types. Steve also discusses using Zod for form validation, coercion, defaults, and type guards, emphasizing the importance of ensuring data integrity throughout the codebase.

Preview

Transcript from the "Advanced Zod Types" Lesson

[00:00:00]
>> Steve Kinney: So Zod does infer all of these things, but you can get a little bit crazier with it. You can do like, let's say hypothetically the body was optional. You can chain this on, and now if you look at the type that came out the other end, it's now optional, right? You can even do something like nullable, right, and now if you look, it's string or null, right, so you can really get to whatever kind of type you're working on, right?

[00:00:29]
You could do like author email. Right, is, there are some that are like, that's technically a string and it'll be a string on the other type, but it will do a check, and this is where it's useful for form validation. Like the type says it's a string, but like when it's validating the data structure, like if it came from a form or whatever, it will actually validate that it is in fact an email address.

[00:00:59]
Or for the like thing we saw earlier. You know, you can validate, like, that's technically a string, but like it will do the validation on the object in runtime as well. And there's a bunch of other fun things. I'm not going to read the entire docs to you and stuff like that, but there is another one that I will say is incredibly useful, right? And a lot of times also if you're working with like LLMs and stuff like that, which is you can give an LLM a Zod schema or like a JSON schema of what you expect, hey, ID should be a number.

[00:01:36]
And like 60% of the time, it'll put a number in there. Right, and 40% of time it'll put the string of the number in there, or the string true. And right now this would technically blow up if someone gave me an ID that was the string of a number. One of the things that I really like to use with Zod is I will use this dot coerce, which means if it gets the string 123, it will to number it. Kind of like what we were talking about earlier, right?

[00:02:11]
If it gets the string true and you have it on like a, like a hypothetically, published, and we say z.coerce. And we say dot boolean, it gets the string true or the number 1 or something like that, it will coerce it into true. Right, the other really great one to kind of like hit on the like story I told earlier with arrays sometimes being null. It's like, let's say we had tags. Right? And I'm going to say that this should be like the array, and it should be of strings.

[00:03:03]
Right, and you gotta put that comma there. This will make sure that it is an array of strings. However, you can also say that default. And given an array, which means if it was null or undefined or something, instead of blowing up, it will swap it in with an empty array. Right, and so like a lot of times like, you can have very, very strict ones that make sure everything is the way you think it is, but a lot of times I don't necessarily want my code to like blow up and show an error because the idea that I want to be a number and all my codebase has a number ended up being the string of the same thing, right?

[00:03:47]
Like, I don't necessarily need like to throw up an error page. Just coerce it. So I will, like, in my codebase have lots of defaults and coerce and optionals and like test it so that like, it will take all of the weird permutations that are like very close to the type I'm expecting and just like massage it into that type. And then I never worry about this again, right? And it's an incredibly, because again, like we're parsing it here.

[00:04:18]
At this point, by the time it comes out of fetch article, I am sure, as you look, I got the type for free effectively. And like all throughout the codebase now, I will know exactly what all of these things are, and they will be correct. You can even like, you know, like, coerce it into like, you know, a date into a number because certain things don't serialize as JSON, right? So even for your own stuff, you parse it, you know, as a number, but coerce, it'll turn it into, you know, the date.now number, and then you can send that to the API, so on and so forth.

[00:04:54]
So for all the things kind of like at the periphery, do you need to do everything in your codebase with this, you don't, because you have TypeScript. Once it's in your codebase, it's fine. You kind of only need it at the doors. Right, to kind of like check IDs or whatever on the way in to make sure everything is what you expect. Once it's in your codebase, you don't necessarily need to do this all the time.

[00:05:20]
But on any of those like periphery parts of your React and TypeScript or honestly, anything project, this becomes a really, really powerful way of making sure everything is what you think it is, and allowing you to kind of like deal with it at the first possible point. So I don't necessarily want to throw an error here. The other thing that you can do that is really powerful with this is there's parse which will throw an error if it doesn't, if it doesn't work and it couldn't coerce and default its way through it, right?

[00:05:53]
The other method that it has on it is what's called safe parse, which will just not throw. But you can do something incredibly powerful with that. Because this is a, like, and let's say even like we had a metadata, I don't know, I'm just making stuff up at this point, we'll say that's a z.record with a key that is a z.string and a value that is a z.unknown, and. Cool, checking to see if something is an object in JavaScript.

[00:06:36]
I'm not going to say it's a nightmare. But it's not fun because like, type of. I'm not going to run this, but like I will, this is a true statement type of null equals equals equals object. You know what else does too, array. Why would you check for an unknown if it, just, I'm curious if, you're supposed to like kind of like theoretically just checking this at the door. Well, because metadata might be arbitrary data, right?

[00:07:07]
And like it could be a number or a boolean or a string. It could be like, you know, they could have typed in anything there, which means it will know that it's an object if you look at this, like, but when I want, let's look at this one instead, like when I want to use that value, I might have to do one more type check. Right. Like the overall, it should have a metadata that is an object that is, you know, has strings for keys.

[00:07:35]
What like JSON, for instance. You know, especially if it's just some arbitrary JSON. If I know always the shape of metadata, totally, but you don't always know, right? And so at that point, yeah, if I knew there was always, and you can even do, watch this, you can do the union. Z.string. And commas today, z.number. Why are you angry with the string? Whatever. What does some type come from? I don't know.

[00:08:25]
I'll deal with that in a moment. Oh, because I'm in the record still, I. Let's go do this over here, like, not where I was doing it before. Put that back to z.unknown. If I say, like, I, there's something where like I'm working on some code right now where like, what is, why are you angry with me? I don't. Why is it not angry about number? I was just angry about the first argument. I don't know. I will look up the docs in a second to see what exactly the issue is, but you could theoretically.

[00:09:06]
Oh, it's an array. It has to be an array of things. It's not just a bunch of arguments. Like, you know, if I stop and think instead of like talking and typing at the same time, boom, problem solved. So you can actually say that it can be a string or a number, or if we're going for the full like JSON thing, z.dot. You know, nullable or null, I think in this case, because that's, and what was it z.boolean, so this could be like any JSON primitive at this point, right?

[00:09:49]
And like that will now, if I did type of on that. You can see that ID could theoretically be any of these. You can get most, you can even do pick and omit and stuff like that as well, with all these. I'm not going to read the entire API. If you can do it in TypeScript, you can usually do it and a few more extra things. But the other really powerful thing that you can do with Zod is what we're going to call type guards.

[00:10:19]
So I can do something where, let's say I have something, I just want to check to see if it is what I think it is. I can do something like function is post and we can say like value is unknown, so like take anything, we don't know anything about it, don't assume it's any, but like, and we could say value is post and I can do return, post schema dot safe parse. And because this doesn't throw, it actually returns either success, data we don't care about, or error, but like, if success, which is a boolean, is true, then anything passed in here from that point forward in the like code will be considered a post.

[00:11:14]
Right, so it won't throw, but if you're like, hey, I got some value from local storage, and I want to see if it is a post, right, this will return true, but from that point forward, like it will be also that type as well. So a lot of times I'll have these too, because like, if you try to even see if something was an object, you gotta make sure that it's not null, make sure that it's not an array. It's like 5 lines I don't ever want to write again.

[00:11:38]
Especially with like nested objects, but you can like now, even if this grew very big, I can now see, is this very thing that I'm dealing with, that I got from somewhere that maybe I'm not entirely sure on the type, or maybe I'm doing like one of those like switch statements or something like that, you can kind of get a sense of what it is. But like Zod will be very good for making sure that things are what you think they are.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now