Sortie de Zod 4
(zod.dev)- Zod 4 est publié en version stable après un an de développement ; il corrige les limites de conception de Zod 3 et améliore fortement les performances, la taille du bundle et l’efficacité de compilation TypeScript
- Zod 3, sorti en mai 2021, est passé de 2 700 étoiles GitHub et 600 000 téléchargements hebdomadaires à 37,8k étoiles et 31 millions de téléchargements hebdomadaires aujourd’hui ; après 24 versions mineures, les principales améliorations nécessitaient des changements incompatibles
- Dans les benchmarks, le parsing de chaînes est 14 fois plus rapide, celui des tableaux 7 fois plus rapide et celui des objets 6,5 fois plus rapide ; les instanciations de types par
tscpassent aussi de plus de 25 000 à environ 175 dans un exemple simple - La taille du bundle cœur passe, en gzip, de
12.47kbpour Zod 3 à5.36kbpour la version standard de Zod 4 ; Zod Mini, une API fonctionnelle compatible avec le tree shaking, descend jusqu’à1.88kb - Les nouveautés incluent la conversion en JSON Schema, un registre de métadonnées, l’inférence de types d’objets récursifs, l’internationalisation, le pretty-printing des erreurs, les types template literal,
z.stringbool(), un paramètreerrorunifié et unz.discriminatedUnion()amélioré
Pourquoi Zod 4 est une nouvelle version majeure
- Zod 4 devient stable après un an de développement actif et implémente des fonctionnalités longtemps demandées sur une base plus rapide, plus légère et plus efficace pour
tsc - Zod v3.0 est sorti en mai 2021 ; à l’époque, il comptait 2 700 étoiles GitHub et 600 000 téléchargements hebdomadaires
- Aujourd’hui, Zod affiche 37,8k étoiles GitHub et 31 millions de téléchargements hebdomadaires
- Il y a six semaines, lors de la bêta, les téléchargements hebdomadaires étaient de 23 millions
- Après 24 versions mineures, la base de code de Zod 3 a atteint ses limites, et les fonctionnalités et améliorations les plus demandées nécessitaient des changements incompatibles
- Zod 4 ferme 9 des 10 issues publiques ayant reçu le plus de votes
Performances de parsing et efficacité de compilation TypeScript
- Zod 4 fournit des benchmarks exécutables directement depuis le dépôt
- Améliorations des performances de parsing :
- Parsing de chaînes : 14 fois plus rapide
- Parsing de tableaux : 7 fois plus rapide
- Parsing d’objets : 6,5 fois plus rapide
- Le benchmark de parsing d’objets exécute le benchmark des bibliothèques de validation de Moltar
- Avec
tsc --extendedDiagnostics, les instanciations de types diminuent fortement lors de la compilation d’un fichier simple- Avec
"zod/v3": plus de 25 000 - Avec
"zod/v4": environ 175
- Avec
- Zod 4 évite l’explosion des instanciations en repensant et simplifiant les génériques de
ZodObjectet des autres classes de schémas - Le motif consistant à chaîner plusieurs fois
.extend()et.omit()prenait4000msà compiler avec Zod 3, et un appel.extend()supplémentaire pouvait provoquer une erreur"Possibly infinite" - Le même motif compile en
400msavec Zod 4, soit 10 fois plus vite - À l’avenir, utilisé avec le compilateur
tsgo, Zod 4 pourrait faire évoluer les performances dans l’éditeur vers des schémas et bases de code encore plus grands
Taille du bundle et Zod Mini
- Un simple script de validation
z.boolean()est bundlé avecrolluppour comparer la taille du bundle cœur - Taille du bundle cœur en gzip :
- Zod 3 :
12.47kb - Version standard de Zod 4 :
5.36kb
- Zod 3 :
- Le bundle cœur de la version standard de Zod 4 est environ 57 % plus petit que celui de Zod 3, soit une réduction d’un facteur 2,3
- L’API de Zod centrée sur les méthodes est fondamentalement difficile à tree shaker, et même un simple script
z.boolean()embarque aussi des implémentations de méthodes inutilisées comme.optional()et.array() - Zod Mini fournit une API fonctionnelle, compatible avec le tree shaking, correspondant 1:1 à
zod- Là où Zod utilise des méthodes, Zod Mini utilise généralement des fonctions wrapper
- Les méthodes de parsing sont identiques entre Zod et Zod Mini
- Une méthode générique
.check()permet d’ajouter des raffinements
- Zod standard reste recommandé pour la plupart des cas d’usage, tandis que les projets soumis à des contraintes de taille de bundle exceptionnellement strictes peuvent envisager Zod Mini
- Avec
zod/mini, la taille du bundle gzip est de1.88kb- Soit 85 % de moins que Zod 3, une réduction d’un facteur 6,6
- Tableau comparatif : Zod 3
12.47kb, Zod 4 standard5.36kb, Zod 4 Mini1.88kb
- Plus de détails sont disponibles dans la documentation
zod/mini
Métadonnées et JSON Schema
- Zod 4 introduit un nouveau système pour ajouter aux schémas des métadonnées fortement typées
- Les métadonnées sont stockées non pas dans le schéma lui-même, mais dans un registre de schémas qui associe les schémas à des typed metadata
- Il est possible de créer un registre avec
z.registry(), et la méthode.register()des schémas permet aussi un enregistrement pratique - Zod exporte un registre global,
z.globalRegistry, qui accepte les métadonnées courantes compatibles JSON Schema - La méthode
.meta()ajoute facilement un schéma àz.globalRegistry - Pour la compatibilité avec Zod 3,
.describe()reste disponible, mais.meta()est recommandée dans Zod 4 - Zod 4 fournit une conversion JSON Schema first-party via
z.toJSONSchema() - Les métadonnées de
z.globalRegistrysont automatiquement incluses dans la sortie JSON Schema - Les informations de personnalisation du JSON Schema généré se trouvent dans la documentation JSON Schema
Nouvelles expressions de schémas et fonctionnalités de typage
- Zod 4 peut correctement inférer les types d’objets récursifs
- Il permet d’exprimer des types récursifs et des types mutuellement récursifs
- Contrairement au motif de types récursifs de Zod 3, aucun cast de type n’est nécessaire
- Le schéma obtenu est une instance
ZodObjectstandard et peut utiliser toutes ses méthodes
- Un schéma File a été ajouté pour valider les instances de
File z.templateLiteral()exprime les types template literal de TypeScript- Les types de schémas Zod convertibles en chaîne stockent une expression régulière interne
- Les cibles incluent les chaînes, les formats de chaînes comme
z.email(), les nombres, les boolean, les bigint, les enum, les literal, undefined/optional, null/nullable et d’autres template literal - Le constructeur
z.templateLiteralles concatène en une super-regex - Les formats de chaînes comme
z.email()sont bien appliqués, mais les custom refinement ne le sont pas - Plus de détails dans la documentation sur les template literal
- De nouveaux formats numériques représentant des entiers de largeur fixe et des types à virgule flottante ont été ajoutés
- Ils renvoient une instance
ZodNumberavec les contraintes inclusive minimum/maximum appropriées déjà ajoutées
- Ils renvoient une instance
- Des formats numériques bigint dépassant la plage représentable de manière sûre par un
numberJavaScript ont aussi été ajoutés- Ils renvoient une instance
ZodBigIntavec les contraintes inclusive minimum/maximum appropriées déjà ajoutées
- Ils renvoient une instance
z.literal()peut désormais accepter plusieurs valeurs de façon optionnelle
Erreurs, internationalisation et formats de chaînes
- Zod 4 introduit une nouvelle API
localespour traduire globalement les messages d’erreur dans plusieurs langues - La liste complète des locales prises en charge se trouve dans Customizing errors et sera mise à jour à mesure que des langues seront ajoutées
- Zod implémente une fonction de haut niveau
z.prettifyErrorqui transforme uneZodErroren chaîne dans un format convivial- Le format actuel n’est pas configurable
- Il pourra changer à l’avenir
- Si vous utilisez déjà
zod-validation-error, vous pouvez continuer à l’utiliser
- Tous les formats de chaînes, dont email, sont promus en fonctions de haut niveau du module
z- C’est plus concis et plus favorable au tree shaking
- Les API équivalentes sous forme de méthodes, comme
z.string().email(), restent utilisables mais sont deprecated - Elles seront supprimées dans la prochaine version majeure
- L’API
z.email()prend en charge les custom regular expressions- Il n’existe pas de regex email canonique unique, et chaque application peut choisir des critères plus stricts ou plus souples
- Zod exporte quelques expressions régulières courantes par commodité
Conversion de booléens et simplification de la personnalisation des erreurs
- L’ancien
z.coerce.boolean()est une API simple qui convertit les valeurs falsy enfalseet les valeurs truthy entruefalse,undefined,null,0,"",NaN, etc. deviennentfalse- Ce comportement est cohérent avec les autres API
z.coerce
- Pour une coercition de boolean plus élaborée façon variables d’environnement, Zod 4 introduit
z.stringbool()- Les valeurs truthy et falsy peuvent être personnalisées
- Plus de détails dans la documentation de
z.stringbool()
- La plupart des changements incompatibles de Zod 4 concernent l’API de personnalisation des erreurs
- La personnalisation des erreurs est unifiée dans un seul paramètre
errormessageest remplacé parerror- Le paramètre
messagereste pris en charge mais est deprecated invalid_type_erroretrequired_errorsont remplacés par la syntaxe fonctionnelle deerrorerrorMapest également remplacé par la syntaxe fonctionnelle deerror
Composabilité, raffinements et transformations
z.discriminatedUnion()prend en charge plusieurs types de schémas qui ne l’étaient pas auparavant- Cela inclut les unions et les pipes
- Une discriminated union peut être utilisée comme membre d’une autre discriminated union, ce qui la rend composable
- Dans Zod 3, les raffinements étaient stockés dans la classe
ZodEffects, qui enveloppait le schéma d’origine- Cette structure rendait peu pratique la combinaison de
.refine()avec d’autres méthodes de schéma comme.min()
- Cette structure rendait peu pratique la combinaison de
- Dans Zod 4, les raffinements sont stockés à l’intérieur du schéma, ce qui permet d’utiliser naturellement
.refine()avec les autres méthodes de schéma - La nouvelle méthode
.overwrite()exprime une transformation qui ne change pas l’inferred type.transform()produit un type de sortie qui n’est pas introspectable à l’exécution, et la fonction de transformation peut renvoyer n’importe quoi : c’est une boîte noire- Il n’existe donc pas de moyen sûr de la convertir en JSON Schema
.overwrite()renvoie une instance de la classe d’origine- La fonction overwrite est stockée comme un raffinement et ne modifie pas l’inferred type
- Les méthodes existantes
.trim(),.toLowerCase()et.toUpperCase()ont été réimplémentées avec.overwrite()
Une base pour les auteurs de bibliothèques
- L’ajout de Zod Mini a entraîné la création du sous-paquet
zod/v4/core, qui contient les fonctionnalités cœur partagées par Zod et Zod Mini zod/v4/corefait évoluer Zod d’une simple bibliothèque vers une base de validation rapide pouvant être intégrée à d’autres bibliothèques- Si vous créez une bibliothèque de schémas, vous pouvez vous appuyer sur
zod/v4/coreen vous inspirant des implémentations de Zod et Zod Mini - Un guide For library authors est fourni pour les auteurs de bibliothèques
- Il couvre les best practices lors de la construction au-dessus de Zod
- Il répond aux questions fréquentes sur la prise en charge simultanée de Zod 3, Zod 4 et Mini
1 commentaires
Avis sur Hacker News
Je suis l’auteur, posez-moi vos questions. J’ai expliqué assez en détail les raisons de cette approche concernant la politique de versionnement : https://github.com/colinhacks/zod/issues/4371
Au final, npm n’est pas conçu pour bien gérer la situation dans laquelle se trouve Zod. Des dizaines, voire des centaines de bibliothèques importent directement les interfaces/classes de Zod et les utilisent dans leur API publique ; à chaque montée de version majeure de Zod, ces bibliothèques doivent donc elles aussi publier une nouvelle version majeure
Pris isolément, c’est raisonnable, mais avec Zod cela peut provoquer une avalanche de versions douloureuse pour tout le monde, et il semblait probable qu’une bonne partie de l’écosystème reste bloquée indéfiniment sur la v3
Nous avons donc choisi une approche proche de celle de Go : au lieu de publier une nouvelle version du paquet introduisant une rupture de compatibilité, ajouter un nouveau sous-chemin. Dans l’écosystème TypeScript, une bibliothèque peut avoir une seule peer dependency
zod@^3.25.0et prendre ce dont elle a besoin depuis"zod/v3"et"zod/v4"afin de prendre en charge les deux versions en même tempsCela dit, même si je comprends pourquoi cette politique de versionnement un peu étrange a été choisie en raison de circonstances particulières, du point de vue d’une équipe qui n’a pas à se soucier des conflits de versions de Zod dans les dépendances transitives, j’aurais aimé qu’il existe aussi un paquet
4.0.0Si j’ai bien compris, il faut remplacer les imports par
"zod/v4", ce qui est un changement très bruyant, et il peut être pénible de devoir attraper via une règle de lint les imports automatiques de l’IDE depuis'zod'.optional()dans TypeScript fait partie des 9 ou 10 principaux tickets résolus : https://github.com/colinhacks/zod/issues/635C’était mon plus gros point de friction avec Zod, mais Zod est tellement bon que je fais avec malgré tout
Je me demande si vous considérez que cela sort du périmètre de Zod, ou si vous n’avez simplement pas encore eu le temps de l’implémenter. La discussion associée est ici : https://github.com/colinhacks/zod/discussions/2134
3.25.0, ça me semble assez absurdeJ’utilise les versions alpha de Zod depuis plusieurs mois et je voulais simplement modifier
package.jsonpour faire la mise à niveau, mais maintenant j’ai l’impression que je vais devoir fouiller tout l’historique gitJe suis très reconnaissant pour ce projet, mais sur ce point précis, j’ai l’impression que ce retour d’expérience a été rendu inutilement difficile. Il aurait peut-être été possible de publier aussi une 4.x en parallèle de la
3.xLe fait de « distribuer Zod 4 avec Zod 3 dans la release
zod@3.25, afin de simplifier la migration, et de l’importer depuis le sous-chemin"/v4"» ressemble à un signe que la gestion des dépendances npm est complètement bancaleLes peer dependencies sont tellement cassées que la v4 doit faire semblant d’être la v3
Il est vrai que npm ne gère pas bien la situation dans laquelle se trouve Zod. Cela dit, Zod a pour contrainte de ne quasiment dépendre d’aucune autre bibliothèque. Des dizaines, voire des centaines de bibliothèques importent directement des interfaces/classes depuis
"zod"et les utilisent dans leur API publiqueCes bibliothèques doivent publier une nouvelle version majeure à chaque montée de version majeure de Zod, et dans le cas de Zod cela peut provoquer une avalanche de versions douloureuse pour tout le monde. Honnêtement, il semblait probable qu’une bonne partie de l’écosystème reste bloquée indéfiniment sur la v3
Nous avons donc choisi une approche similaire à Go : au lieu de publier une nouvelle version du paquet à chaque release avec rupture de compatibilité, ajouter un nouveau sous-chemin. Dans l’écosystème TypeScript, une seule peer dependency
zod@^3.25.0permet de prendre en charge simultanément"zod/v3"et"zod/v4"Autrement dit, refactoriser les usages un par un vers
import ... from 'zod/v4', puis, une fois terminé, passer entièrement à la v4Au contraire, npm offre davantage de portes de sortie, puisqu’il permet, si nécessaire, d’exécuter plusieurs versions en parallèle ou d’écraser sélectivement une partie du graphe des dépendances transitives
Quel système de gestion de paquets résout ce problème ? Même des plateformes « stables » comme Maven traitent ce genre de situation en publiant les versions sous de nouveaux namespaces, comme lorsque Apache Commons est passé de v2 à v3
Il y a une question que je me pose depuis longtemps. J’ai entendu dire que Zod pouvait convenir à ce cas, mais même en lisant la documentation, je ne vois pas bien comment faire.
Imaginons que l’API serveur renvoie des types plus précis que ce qu’elle peut exprimer. Par exemple,
api/:postid/authorrenvoie un User, mais il peut s’agir d’un User normal ou d’un User anonyme, si bien que des champs commeusernameoulocationpeuvent arriver ànull. Dans ce cas, on peut vouloir représenter l’objet User comme une union discriminée.Les objets provenant d’autres endpoints peuvent aussi nécessiter une conversion de type. Un User peut parfois inclure des
Post[], et si un Post est un message de modérateur, il peut aussi avoir des propriétés spéciales.Avant, j’écrivais des fonctions comme
normalizeUser()etnormalizePost(), mais c’est vite devenu brouillon. Comme chaque endpoint renvoyait un sous-ensemble différent des modèles User/Post, je me suis retrouvé avec environ cinqnormalizePost, et c’était beaucoup trop désordonné. Je me demande comment on résout généralement ce genre de problème.On sépare par exemple les objets
successetfailedà partir d’un champ discriminant commestatus. S’il y a beaucoup de propriétés spéciales pour les modérateurs, mais qu’on ne veut pas toutes les énumérer ni les vérifier, on peut définir un comportement de passage.Même si plusieurs méthodes ont des schémas différents, s’il existe une partie commune, on peut créer un schéma d’objet partagé, puis construire des objets qui y ajoutent des champs supplémentaires. S’il y a beaucoup de possibilités, cela restera désordonné, mais si la situation est déjà désordonnée, un validateur peut au moins valider ce désordre.
Si ce n’est pas du TypeScript full stack, par exemple avec un backend Python, on peut définir les différentes formes de
Useravec des modèles Pydantic et des unions, puis générer un schéma OpenAPI/GraphQL et produire les types du client TypeScript par génération de code."user_type"à tous les types de l’union facilite la gestion des cas généraux et particuliers.Par exemple, si l’on vérifie
user.user_type === 'authenticated', le système de types sait ensuite queuser.namepeut être utilisé.Les bibliothèques TypeScript pour requêtes GraphQL peuvent inférer dynamiquement la forme de la réponse à partir des champs sélectionnés. Si l’on sélectionne
{ user { username posts { text } } }, le type de réponse inclutposts; si l’on ne sélectionne que{ user { username } }, la propriétépostsdisparaît complètement.Le serveur sait quelles données il envoie, il doit donc fournir cette information au client sous forme de métadonnées. En pratique, cela peut vouloir dire qu’un backend Python utilise des schémas Pydantic, génère automatiquement une spécification OpenAPI à partir de ceux-ci, puis que le client génère ses types.
Zod est nettement meilleur que les alternatives que j’ai vues, mais le fait même d’avoir besoin de cette validation explicite ressemble parfois à un échec de l’endroit où en est arrivé le développement web moderne.
En développement full stack, c’est très frustrant de devoir décrire la même forme de plusieurs manières. On finit par avoir besoin de validation des entrées en JS, de Swagger pour la définition d’API, de validation des entrées côté serveur, d’un ORM pour la conformité au schéma, et de définitions TypeScript séparées côté serveur et côté client, ce qui devient fastidieux.
TypeScript donne l’impression d’être la meilleure source unique de vérité dont nous disposions, mais en réalité les outils qui tentent de faire de la réflexion redéfinissent chacun leur propre modèle et leur propre builder. Il existe à lui seul cinq grands domaines où la réflexion est centrale, chacun avec plusieurs implémentations.
L’ancien outil d’émission de types TypeScript
reflect-metadatafournit une partie des informations de type à l’exécution, mais il cible de très anciennes spécifications de décorateurs et de métadonnées : https://www.npmjs.com/package/reflect-metadataPeut-être en sommes-nous au tout début d’une unification. Le projet Standard Schema semble pris en charge par la plupart des grandes bibliothèques de validation. Cela dit, l’étendre jusqu’aux outils de définition d’API ou aux ORM en est encore à un stade très précoce.
https://github.com/standard-schema/standard-schema?tab=readm...
Quand on modifie une fois le schéma Zod, cela se propage à toute l’application avec la vérification de types. Le schéma Zod devient en quelque sorte la source unique de vérité.
Si l’on dispose déjà d’un schéma JSON Schema/Swagger, il suffit de générer Zod à partir de celui-ci. Si l’on utilise un ORM TypeScript, il y a presque certainement un générateur Zod.
Franchement, Zod est tellement répandu qu’à mes yeux il devient une définition de schéma unifiée sur laquelle le reste de la stack peut s’appuyer. Comme les types sont définis directement, les développeurs les maintiennent réellement à jour. La documentation Swagger de mon entreprise est toujours en retard sur les changements.
Le statu quo ne convient que lorsqu’on a affaire à des clients et des employeurs qui veulent simplement le résultat et ne s’intéressent pas à la manière. Dans ce contexte, ces malheureuses couches de complexité augmentent au moins le temps facturable.
En supposant bien sûr que Zod soit la bibliothèque de définition de schémas et de validation TypeScript qu’ils ont choisie.
Zod 4 a l’air prometteur, mais même avec les dernières améliorations, ArkType reste plusieurs fois plus rapide, et encore avec un facteur à un chiffre.
Pour des raisons de rétrocompatibilité et de compatibilité syntaxique, il est parfois difficile de faire aussi rapide qu’une bibliothèque repartie complètement de zéro. J’ai analysé tous ces outils dans un projet récent et j’ai choisi ArkType en partie pour cette raison. L’expérience TypeScript m’a aussi semblé meilleure.
Nous n’utilisons Zod que pour la validation de formulaires, donc je me dis : « pourquoi est-ce important ? ». Peut-être que des gens valident des choses comme des messages d’entrée d’API à haut débit, où les performances deviennent plus importantes.
Cela dit, je ne pense pas quitter Zod.
Félicitations à l’équipe Zod pour cette nouvelle version. Même au risque de paraître trop négatif, le nombre de changements cassant la compatibilité indiqués dans le guide de migration me donne des frissons.
Pour un projet qui dépend fortement de Zod, cela ressemble à une tâche intimidante qui demandera beaucoup de concentration et de temps aux développeurs. Cela me parle particulièrement, ayant maintenu au travail plusieurs projets frontend âgés de 4 à 5 ans.
Les gros projets React dépendent généralement de nombreuses bibliothèques, et quand chacune publie de gros changements, surtout avec une documentation insuffisante, on est vite submergé. C’est l’un des aspects que je déteste le plus dans le travail avec JavaScript : garder tout aligné et continuer à faire tourner l’ensemble sans heurts donne l’impression d’une montée interminable.
Franchement, ça a été un cauchemar, et je me suis dit que j’aurais préféré que ce soit fait avec Django. Contrairement à ce que j’attendais, la migration Tailwind 3 → 4 a été parmi les plus douloureuses.
miniséparée. Cela facilite une migration progressive sans toucher au gestionnaire de paquets.Les utilisateurs qui ne s’intéressent pas à l’édition
minin’ont pas besoin de s’en préoccuper. Mais les avantages de tree shaking de l’éditionminiétaient si importants qu’ils encourageaient le développement d’alternatives, et Zod devait soit les adopter, soit décliner.En tant que développeur full-stack exploitant moi-même un SaaS en production avec des milliers d’utilisateurs, je suis parfois agréablement surpris de constater combien de problèmes m’échappent totalement parce que j’ai choisi de ne pas faire de SPA et de ne pas utiliser de framework frontend JS.
Je n’ai même jamais pensé avoir besoin de choses comme Zod/ArkType, je n’en avais jamais entendu parler, et je n’en aurai pas l’usage.
Je suis étonné par la quantité d’efforts, de complexité et d’outils nécessaires pour créer une SPA. Quand on décide de ne pas créer de SPA, toute une catégorie de problèmes cesse tout simplement d’exister. À la place, on utilise le navigateur comme il a été conçu à l’origine, avec des rechargements complets de page et un développement centré sur le backend, en ajoutant parfois de la réactivité avec un framework exclusivement backend comme Laravel Livewire.
Tout est plus simple, du contrôle d’accès à la validation en passant par la gestion d’état. L’app est rapide, responsive, moderne, SEO-friendly, et sert des milliers d’utilisateurs en production.
Au bout du compte, il y a bien un schéma quelque part. Il peut être défini dans le système de base de données ou dans les modèles de l’ORM. Mais dans de gros projets, placer le schéma dans le système de base de données ou l’ORM peut créer des problèmes très difficiles, donc nous utilisons Zod et Protobuf. À mon avis, Protobuf pourrait aussi être entièrement remplacé par Zod ou quelque chose de similaire.
Le scandale du Post Office britannique implique un système informatique appelé Horizon : https://en.wikipedia.org/wiki/British_Post_Office_scandal
En lisant les détails, j’ai l’impression qu’une validation de schéma comme Zod aurait pu contribuer à empêcher ce scandale. L’annexe technique des documents judiciaires du recours collectif mentionne aussi l’absence d’utilisation de schémas : https://en.wikipedia.org/wiki/Bates_%26_Others_v_Post_Office...
Pour l’instant, on dirait que vous écrivez défensivement une tonne de
if. Pire encore, vous vous reposez peut-être uniquement sur la validation de formulaires HTML côté client.Je ne suis pas expert, donc je reste prudent, mais je me disais que JSON Schema, étant fondé sur des schémas, pouvait être un bon choix puisqu’il permet d’implémenter des validateurs dans des langages autres que TypeScript
https://ajv.js.org est l’une de ces bibliothèques JSON Schema. Je me demande comment elle se compare à Zod
Si on le souhaite, il peut aussi servir de convertisseur JSON. Par exemple, on peut écrire un schéma qui reçoit une chaîne, vérifie qu’il s’agit d’une chaîne de date ISO et produit un objet
DateLa différence importante concerne le prétraitement et
refine. Dans Zod, on peut fournir un callback avant la validation, ce qui est très utile mais impossible à représenter en JSON. Par exemple, transformerMM/DD/YYYYenDD/MM/YYYYavant la validation d’une date s’avère plus souvent utile qu’on ne le pensePour la validation, on peut utiliser AJV ou le système de validation de schémas propre à TypeBox. Ce dernier est beaucoup plus rapide, mais ne prend en charge que le synchrone, tandis qu’AJV propose des options de validation asynchrone, comme des vérifications en base de données
Les réactions négatives autour de ce sujet me surprennent
J’ai testé une première version de Zod v4 et j’ai apprécié la nouvelle API, mais j’étais très inquiet de ce à quoi ressemblerait le chemin de migration. J’envisageais même de proposer de la publier sous un tout nouveau nom de package
Mais l’approche de l’auteur est intelligente. Elle permet à des personnes comme moi d’adopter v4 immédiatement, sans attendre que toutes les dépendances soient mises à jour
Je venais tout juste de commencer à adopter Zod dans un nouveau projet, et le moment ne pouvait pas être mieux choisi
D’après ce que je vois maintenant, il aurait vraiment fallu changer beaucoup de choses pour passer à v4