GitShow/colinhacks/zod
colinhacks

zod

TypeScript-first schema validation with static type inference

by colinhacks
runtime-validationschema-validationstatic-typestype-inferencetypescript
Star on GitHubForkWebsitenpm

TypeScript

43.1k stars2.0k forks542 contributorsActive · 2w agoSince 2020v4.4.3MIT

Meet the team

See all 542 on GitHub →
colinhacks
colinhacks845 contributions
JacobWeisenburger
JacobWeisenburger63 contributions
scotttrinh
scotttrinh42 contributions
jeremyBanks
jeremyBanks16 contributions
igalklebanov
igalklebanov14 contributions
samchungy
samchungy13 contributions
tmcw
tmcw13 contributions
alexxander
alexxander12 contributions

Languages

View on GitHub →
TypeScript89.3%
MDX9.5%
HTML0.7%
JavaScript0.4%
CSS0.1%
Shell0%

Commit activity

Last 12 weeks · 118 commits

Full graph →

Community health

4 of 6 standards met

Community profile →
85
✓README✓License✓Contributing✓Code of Conduct○Issue Template○PR Template

Recent PRs & issues

Active · Last activity 2w ago
See all on GitHub →
qlufiq-collab
Schema in object being inferred differently (and weirdly)OpenPR

Closes #2654 Summary t equality — fails if EventName2 is the buggy // (string undefined) intersection. util.assertEqual(true); + + // EventName2 must not include undefined. + util.assertEqual(true); expect(EventSchema.parse({ name: "x" })).toEqual({ name: "x" }); expect(EventSchema.parse({ name: ["x"] })).toEqual({ name: ["x"] }); ┊ review diff a/packages/zod/src/v3/tests/issue-2654.test.ts → b/packages/zod/src/v3/tests/issue-2654.test.ts @@ -4,23 +4,30 @@ import as z from "zod/v3"; import { util } from "../helpers/util.js"; test("issue #2654: union inside z.object should infer the same as standalone union", () => { +// Repro for issue #2654 +test("issue #2654: union type used inside z.object infers same as standalone", () => { const EventNameSchema = z.string().or(z.array(z.string())); type EventName = z.infer; const EventSchema = z.object({ name: z.string().or(z.array(z.string())), }); type EventWithName = z.infer; type EventName2 = EventWithName["name"]; + type EventName2 = z.infer["name"]; // Strict, invariant equality — fails if EventName2 is the buggy // (string undefined) intersection. + // Strict invariant equality — fails to compile if the inferred property + // type is the buggy + // intersection instead of . util.assertEqual(true); // EventName2 must not include undefined. + // The property type must not include undefined. util.assertEqual(true); + // Assignability is preserved with the fix: a value of either type works. + const a: EventName = "x"; + const a2: EventName2 = a; + const b: EventName = a2; + expect(b).toBe("x"); + expect(EventSchema.parse({ name: "x" })).toEqual({ name: "x" }); expect(EventSchema.parse({ name: ["x"] })).toEqual({ name: ["x"] }); + expect(EventSchema.parse({ name: ["x", "y"] })).toEqual({ name: ["x", "y"] }); }); ┊ review diff a/packages/zod/probe-2654.ts → b/packages/zod/probe-2654.ts @@ -0,0 +1,26 @@ +import as z from "zod/v3"; + +const EventNameSchema = z.string().or(z.array(z.string())); +type EventName = z.infer; + +const EventSchema = z.object({ + name: z.string().or(z.array(z.string())), +}); +type EventWithName = z.infer; +type EventName2 = EventWithName["name"]; + +// Bivariant equality +type Equals = + (() => T extends A ? 1 : 2) extends + (() => T extends B ? 1 : 2) + ? ((() => T extends B ? 1 : 2) extends (() => T extends A ? 1 : 2) + ? "equal" + : "subset-of-A-not-B") + : "not-equal"; + +type Result = Equals; +declare const r: Result; +// If the bug exists, Result will be "not-equal" or similar — this assignment +// will fail. If the types match, Result is "equal" and assignment succeeds. +const ok: "equal" = r; +console.log(ok); ┊ review diff a//home/azureuser/.cache/bounty-hunter/colinhacks_zod-2654/repo/packages/zod/probe-2654.ts → b//home/azureuser/.cache/bounty-hunter/colinhacks_zod-2654/repo/packages/zod/probe-2654.ts @@ -20,7 +20,6 @@ type Result = Equals; declare const r: Result; // If the bug exists, Result will be "not-equal" or similar — this assignment // will fail. If the types match, Result is "equal" and assignment succeeds. const ok: "equal" = r; +// FORCE FAIL: r should be "equal" but we expect "not-equal" to show the bug +const ok: "not-equal" = r; console.log(ok); ┊ review diff a/packages/zod/probe-2654.ts → b/packages/zod/probe-2654.ts @@ -9,17 +9,18 @@ type EventWithName = z.infer<typeof EventSchema

qlufiq-collab · 5h ago
MerlijnW70
fix(core): detect promises robustly when globalThis.Promise is patchedOpenPR

Fixes #6019. Problem When is replaced by a subclass — Zone.js's , Angular NgZone, , etc. — zod silently drops issues added inside an /, and resolves "successfully" before the async refinement runs: Reported in production via : a duplicate-email check silently let invalid submissions through. Cause A native promise returned from a user function is not the patched global (a subclass), so zod's checks treated the async result as a synchronous value. The native-ness then propagated up the parse chain — native yields native promises — so every downstream check failed too, and never awaited the refinement. Fix Add , which keeps the fast path and falls back to the tag. That tag is shared across promise subclasses and realms, while still excluding ordinary thenable objects: Every promise check in the parse pipeline (, transforms, codecs, objects, unions, records, pipes, /, …) now uses it. In an unpatched runtime the fast path matches exactly as before, so behavior is unchanged; only foreign/subclass promises that previously slipped through are now detected. Tests Added a regression test in that swaps for a subclass (restored in ) and asserts that an fails the parse and an resolves correctly. Verified red without the fix, green with it. Full v4 suite (2764 tests) passes. _Restores #6116, which closed automatically when my fork was briefly deleted. The fix commit is unchanged._

MerlijnW70 · 1d ago
codinsonn
docs: add fullproduct.dev to v4 ecosystem pageOpenPR

Summary Adds FullProduct.dev to the Zod Ecosystem section & page What is FullProduct.dev, how is it powered by Zod? It's a universal app starterkit built around using Zod as the single source of truth: Expands Zod schemas (v3 + v4 + mini) with powerful additional metadata and introspection API's Transform zod component prop schemas to Interactive MDX docs with Nextra Scaffold out an auto-generated graphql schema (+ queries) from your resolver's Zod input and output schemas Plugins to create DB models from Zod schemas to e.g. Mongoose Models hook to further keep things in sync Related V3 PR that got merged into V3 docs: #4131 How Zod is used as the core for Single Sources of Truth: https://fullproduct.dev/docs/single-sources-of-truth

codinsonn · 1d ago

Recent fixes

View closed PRs →
bibulle
Sorry, wrong repo :-(ClosedIssue
bibulle · 12h ago
VihaanAgarwal
fix(toJSONSchema): preserve default value through pipe/transform in input modeMergedPR

Problem passed to silently drops the keyword: Fixes #6049. Root cause in runs after every processor and unconditionally deletes when the check returns . For a whose inner type is a containing a transform, returns — so the value that just set on the schema is immediately wiped. The deletion was intended for cases where is inherited from a pipe (output-side default), not for , which always declares an explicit input-side default. Fix Skip the step when . The processor always sets intentionally; removing it here is wrong regardless of whether the inner type transforms. Test changes Updated existing snapshot for (type-changing transform): with this fix, now appears in the input schema. The keyword in JSON Schema is advisory and does not need to validate against the schema type, so this is spec-compliant and more informative for tooling. Added a new test reproducing the exact case from #6049.

VihaanAgarwal · 1d ago
sogav21
Add v4 regression test for object union inferenceMergedPR

Closes #2654 Summary adds a v4 classic type regression test for object properties whose schema is a union created with verifies the inferred object property type remains identical to the standalone schema output type covers the reported object-property inference case Validation

sogav21 · 1d ago
Structured data for AI agents

Repository: colinhacks/zod. Description: TypeScript-first schema validation with static type inference Stars: 43079, Forks: 2044. Primary language: TypeScript. Languages: TypeScript (89.3%), MDX (9.5%), HTML (0.7%), JavaScript (0.4%), CSS (0.1%). License: MIT. Homepage: https://zod.dev Topics: runtime-validation, schema-validation, static-types, type-inference, typescript. Latest release: v4.4.3 (1mo ago). Open PRs: 100, open issues: 128. Last activity: 2w ago. Community health: 85%. Top contributors: colinhacks, JacobWeisenburger, scotttrinh, jeremyBanks, igalklebanov, samchungy, tmcw, alexxander, noritaka1166, dependabot[bot] and others.

·@ofershap

Replace github.com with gitshow.dev