Skip to content

Instantly share code, notes, and snippets.

@rphlmr
Created October 16, 2022 20:38
Show Gist options
  • Save rphlmr/bb2432d21e4a09c3b4c5e3f32e80a758 to your computer and use it in GitHub Desktop.
Save rphlmr/bb2432d21e4a09c3b4c5e3f32e80a758 to your computer and use it in GitHub Desktop.
Zod implements a TypeScript model
// Thanks https://github.com/colinhacks/zod/issues/372#issuecomment-830094773
type Implements<Model> = {
[key in keyof Model]-?: undefined extends Model[key]
? null extends Model[key]
? z.ZodNullableType<z.ZodOptionalType<z.ZodType<Model[key]>>>
: z.ZodOptionalType<z.ZodType<Model[key]>>
: null extends Model[key]
? z.ZodNullableType<z.ZodType<Model[key]>>
: z.ZodType<Model[key]>;
};
export function implement<Model = never>() {
return {
with: <
Schema extends Implements<Model> & {
[unknownKey in Exclude<keyof Schema, keyof Model>]: never;
}
>(
schema: Schema
) => z.object(schema),
};
}
// usage
export type UserModel = {
id: string
phoneNumber: string
email: string | null
name: string
firstName: string
companyName: string
avatarURL: string
createdAt: Date
updatedAt: Date
}
export const UserModelSchema = implement<UserModel>().with({
id: z.string(),
phoneNumber: z.string(),
email: z.string().email().nullable(),
name: z.string(),
firstName: z.string(),
avatarURL: z.string(),
companyName: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
});
@rphlmr
Copy link
Author

rphlmr commented Oct 16, 2022

Force to put nullable optional or nullish when Model requires it.
Unknown properties are forbidden and cause an error 😎

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