Skip to content

Instantly share code, notes, and snippets.

@gsbelarus
Last active January 23, 2023 13:35
Show Gist options
  • Save gsbelarus/2c4647201773f2fe3e4012633a3bb26f to your computer and use it in GitHub Desktop.
Save gsbelarus/2c4647201773f2fe3e4012633a3bb26f to your computer and use it in GitHub Desktop.
Example of Zod usage for the arcticle on dev.to
// link to the article:
// https://dev.to/andreik/zod-validatsiia-i-vyvod-tipov-na-osnovanii-skhiemy-dannykh-4n3l
import { z } from "https://deno.land/x/zod/mod.ts";
const Levels = ['J1', 'J2', 'J3', 'M1', 'M2', 'M3', 'S1', 'S2', 'S3'] as const;
const Skill = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(60)
});
const PureEmployee = z.object({
id: z.string().uuid(),
name:
z.object({
firstName: z.string().regex(/(([A-Z]{1}[a-z]{1,40})(\s[A-Z]{1}[a-z]{1,40})?)/),
lastName: z.string().regex(/[A-Z]{1}[a-z]{1,40}/)
})
.transform( ({firstName, lastName}) => `${firstName} ${lastName}` ),
dob: z.date()
.min(new Date('01-01-1950Z'))
.min(new Date('31-12-2100Z'))
.optional(),
employmentDate: z.date()
.min(new Date('01-01-2000Z'))
.min(new Date('31-12-2100Z')),
dismissalDate: z.date()
.min(new Date('01-01-2000Z'))
.min(new Date('31-12-2100Z'))
.optional(),
level: z.enum(Levels).optional(),
skills: Skill
.array()
.min(1)
.max(100)
.refine( s => (new Set(s.map( i => i.name ))).size === s.length, 'Duplicate skills are not allowed!')
.optional()
});
const Employee = PureEmployee
.refine(
obj => typeof(obj.dob) === 'undefined' ||
(obj.employmentDate.getTime() - obj.dob.getTime()) > 16 * 365 * 24 * 60 * 60 * 1000,
{
message: 'Too young to work!'
}
)
.refine(
obj => typeof(obj.dismissalDate) === 'undefined' ||
(obj.dismissalDate.getTime() >= obj.employmentDate.getTime()),
{
message: 'Dismissal date is before employment!'
}
);
// this will parse successfully
const employee = Employee.parse({
id: 'eceffe7a-bbe6-41e9-bdc3-09b2970a0d8c',
name: {
firstName: 'James',
lastName: 'Bond'
},
dob : new Date('01-01-1980Z'),
employmentDate : new Date('01-01-2010Z'),
dismissalDate : new Date('01-01-2011Z'),
level: 'J1',
skills: [
{ id: 'eceffe7a-bbe6-41e9-bdc3-09b2970a0d8c', name: 'abc' }
]
});
console.log(employee);
// this will parse with errors
console.log(Employee.safeParse({
id: 'eceffe7a-bbe6-41e9-bdc3-09b2970a0d8c',
name: {
firstName: 'James',
lastName: 'Bond'
},
dob : new Date('01-01-1980Z'),
employmentDate : new Date('01-01-2010Z'),
dismissalDate : new Date('01-01-2011Z'),
level: 'J1',
skills: [
{ id: 'eceffe7a-bbe6-41e9-bdc3-09b2970a0d8c', name: 'abc' },
{ id: 'eceffe7a-bbe6-41e9-bdc3-09b2970a0d8c', name: 'abc' }
]
}));
const PM = PureEmployee.extend({
projectName: z.string()
});
// will not parse without project name specified
console.log(PM.safeParse({
id: 'eceffe7a-bbe6-41e9-bdc3-09b2970a0d8c',
name: {
firstName: 'James',
lastName: 'Bond'
},
dob : new Date('01-01-1980Z'),
employmentDate : new Date('01-01-2010Z'),
dismissalDate : new Date('01-01-2011Z'),
level: 'J1',
skills: [
{ id: 'eceffe7a-bbe6-41e9-bdc3-09b2970a0d8c', name: 'abc' }
]
}));
type Employee = z.infer<typeof Employee>;
type PM = z.infer<typeof PM>;
@gsbelarus
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment