Be Specific with Allowed Types
There are two possible solutions to this challenge.
One Solution: Use Unions & Literals
In the first solution, we'll use Zod's union method and pass in an array of literals for "private" and "public":
const Form = z.object({ repoName: z.string(), privacyLevel: z.union([z.lite
Transcript
Matt Pocock: 0:00 This is the first solution. We've got z.union. Inside z.union we are passing an array. An array contains two possibilities. It contains a z.literal and another z.literal.
0:13 These z.literals
, you can use them to represent anything. They represent to you some...Any sort of literal values inside typescripts, rather. You can't use them to represent objects. You can use them to represent numbers or strings or booleans.
0:27 What you end up with is if we say type formType = z.infer<typeof Form>,
then we end up with private or public here. If I were to add another one to this in z.literal...What's the one down here, something-not-allowed. Then, what you get is this test would fail, of course, because we're specifically saying this thing is not allowed. We've now allowed it inside our union.
0:54 The other way to represent this, which is, I'd argue, a bit cleaner, is z.enum. This does exactly the same thing. It's just sort of under the hood. It's a sugar syntax for the other thing. I'm not sure you can parse it in z.literal here. Yeah.
1:09 You just parse in the literal values and it creates an enum for you. Rather, it doesn't create an enum as the way you think of it in TypeScript. It doesn't say PrivacyLevel private public like this. It doesn't do this. Instead, it creates a string literal type for you or a union type.
1:34 We've got FormType = z.infer<typeof Form>.
Here, again, even though we're using a slightly different syntax, it's producing the same thing, private or public in a string union.