Convertir JSON Schema en schéma Zod — Numio
Génère du code de validation Zod à partir d’un JSON Schema avec json-schema-to-zod. Les contraintes comme minLength, minimum, pattern et default deviennent des méthodes Zod chaînées, et les propriétés absentes de "required" reçoivent .optional().
Vous recevez un JSON Schema d’une autre équipe et voulez une validation à l’exécution dans un service TypeScript sans validateur JSON Schema.
Quand l’utiliser
- Vous recevez un JSON Schema d’une autre équipe et voulez une validation à l’exécution dans un service TypeScript sans validateur JSON Schema.
- Vous migrez la validation de formulaires d’un validateur JSON Schema comme Ajv vers Zod et voulez du code généré comme point de départ.
Mode d’emploi
- Collez un JSON Schema dans le panneau JSON Schema.
- Si besoin, ouvrez les paramètres et modifiez Root Schema Name ("schema" par défaut) ; il devient le nom de la const exportée.
- Copiez le code généré, qui importe z depuis "zod", dans votre projet. La conversion s’exécute dans le navigateur.
JSON Schema
{
"type": "object",
"properties": {
"username": { "type": "string", "minLength": 3, "maxLength": 20 },
"age": { "type": "integer", "minimum": 18 },
"contact": {
"oneOf": [
{ "type": "string", "format": "email" },
{ "type": "string", "pattern": "^\\+[0-9]+$" }
]
},
"newsletter": { "type": "boolean", "default": false }
},
"required": ["username", "contact"]
}Schéma Zod
import { z } from "zod"
export const schema = z.object({
username: z.string().min(3).max(20),
age: z.number().int().gte(18).optional(),
contact: z.any().superRefine((x, ctx) => {
const schemas = [
z.string().email(),
z.string().regex(new RegExp("^\\+[0-9]+$")),
]
const errors = schemas.reduce(
(errors: z.ZodError[], schema) =>
((result) => ("error" in result ? [...errors, result.error] : errors))(
schema.safeParse(x),
),
[],
)
if (schemas.length - errors.length !== 1) {
ctx.addIssue({
path: ctx.path,
code: "invalid_union",
unionErrors: errors,
message: "Invalid input: Should pass single schema",
})
…Détails et limites
oneOf est converti en z.any().superRefine(...), qui vérifie qu’exactement un sous-schéma est valide, comme le montre l’exemple.
$ref n’est pas résolu : une propriété référencée devient z.any().
integer ajoute .int(), format "email" ajoute .email() et format "date-time" ajoute .datetime().
additionalProperties: false devient .catchall(z.never()) au lieu de .strict().
FAQ
Comment les types nullables sont-ils gérés ?
"type": ["string", "null"] devient z.union([z.string(), z.null()]), avec .optional() ajouté si la propriété n’est pas requise.
Puis-je renommer le schéma exporté ?
Oui. Définissez Root Schema Name dans les paramètres ; la sortie devient alors export const <name> = ... au lieu de export const schema.
Les definitions et $ref sont-ils pris en charge ?
Non. Une propriété qui utilise $ref devient z.any() ; intégrez donc le schéma référencé en ligne avant la conversion.