Releases: colinhacks/zod
v3.23.0
Zod 3.23 is now available. This is the final 3.x
release before Zod 4.0. To try it out:
npm install zod
Features
z.string().date()
Zod can now validate ISO 8601 date strings. Thanks @igalklebanov! #1766
const schema = z.string().date();
schema.parse("2022-01-01"); // OK
z.string().time()
Zod can now validate ISO 8601 time strings. Thanks @igalklebanov! #1766
const schema = z.string().time();
schema.parse("12:00:00"); // OK
You can specify sub-second precision using the precision
option:
const schema = z.string().time({ precision: 3 });
schema.parse("12:00:00.123"); // OK
schema.parse("12:00:00.123456"); // Error
schema.parse("12:00:00"); // Error
z.string().duration()
Zod can now validate ISO 8601 duration strings. Thanks @mastermatt! #3265
const schema = z.string().duration();
schema.parse("P3Y6M4DT12H30M5S"); // OK
Improvements to z.string().datetime()
You can now allow unqualified (timezone-less) datetimes using the local: true
flag.
const schema = z.string().datetime({ local: true });
schema.parse("2022-01-01T12:00:00"); // OK
Plus, Zod now validates the day-of-month correctly to ensure no invalid dates (e.g. February 30th) pass validation. Thanks @szamanr! #3391
z.string().base64()
Zod can now validate base64 strings. Thanks @StefanTerdell! #3047
const schema = z.string().base64();
schema.parse("SGVsbG8gV29ybGQ="); // OK
Improved discriminated unions
The following can now be used as discriminator keys in z.discriminatedUnion()
:
ZodOptional
ZodNullable
ZodReadonly
ZodBranded
ZodCatch
const schema = z.discriminatedUnion("type", [
z.object({ type: z.literal("A").optional(), value: z.number() }),
z.object({ type: z.literal("B").nullable(), value: z.string() }),
z.object({ type: z.literal("C").readonly(), value: z.boolean() }),
z.object({ type: z.literal("D").brand<"D">(), value: z.boolean() }),
z.object({ type: z.literal("E").catch("E"), value: z.unknown() }),
]);
Misc
- feature: allow falsy error message by @fernandollisboa in #3178
- feature: add attribute message to enum validatiion by @fernandollisboa in #3169
Breaking changes
There are no breaking changes to the public API of Zod. However some changes can impact ecosystem tools that rely on Zod internals.
ZodFirstPartySchemaTypes
Three new types have been added to the ZodFirstPartySchemaTypes
union. This may impact some codegen libraries. #3247
+ | ZodPipeline<any, any>
+ | ZodReadonly<any>
+ | ZodSymbol;
Unrecognized keys in .pick()
and .omit()
This version fixes a bug where unknown keys were accidentally accepted in .pick()
and omit()
. This has been fixed, which could cause compiler errors in some user code. #3255
z.object({
name: z.string()
}).pick({
notAKey: true // no longer allowed
})
Bugfixes and performance
- Bugfix: Enum.extract/exclude should not remove error mapping by @shaharke in #3240
- Added latest stable Node and TypeScript versions to test matrix for up-to-date testing. by @m10rten in #3278
- Add types to
ZodFirstPartySchemaTypes
by @MatthijsMud in #3247 - fix: make
input
of.required()
readonly by @KATT in #3301 - add never props to safe parse return types by @schicks in #3295
- Reporting errors of the preprocess that is the second property of object by @yukukotani in #2912
- Improve
addQuestionMarks
, fix #2184 by @colinhacks in #3352 - fix for njs by @dvv in #3063
- only look in
src
forbun test
by @rotu in #3038 - Restrict .pick()/.omit() mask type to only known properties by @petrovmiroslav in #3255
- Make EnumValues generic by @IlyaSemenov in #2338
- perf: avoid unnecessary error maps by @xuxucode in #2532
- Bugfix: z.record().parse should not filter out undefined values by @raik-casimiro in #3251
- Use Set.has instead of Array.indexOf for enum comparison (perf improvement) by @jmike in #2659
- [2888] fix emails with single quotes failing validation by @Mansehej in #2889
- Bugfix: Commas are incorrectly allowed in email regex. by @mokemoko in #3286
- Fix regex in cuid2 validation to be what cuid2 library expects by @etareduction in #2961
- Make depcruise pass by @rotu in #3037
- Faster ipv4 parsing by @colinhacks in #3413
Docs and ecosystem
- chore: add pastel package to ecosystem by @jlarmstrongiv in #2949
- added required styles. by @Ansh101112 in #2955
- Feature/better chinese translate by @NWYLZW in #2988
- Fix z.instanceof example by @alexnault in #3003
- Add documentation to Zod enum exclude/extract functions by @shaharke in #3044
- Add docs for coercing nullish values by @rbuetzer in #3067
- Adds
zod-dev
utility to eco-system section by @schalkventer in #3113 - Add zhttp library to docs by @evertdespiegeleer in #3134
- fixed Readme typo in NaNs example by @RashJrEdmund in #3181
- adds zod-config library to the ecosystem by @alexmarqs in #3200
- docs: update link and description of conform integration by @g1eny0ung in #3238
- Update README.md by @yugmade13 in #3317
- feat: overhaul generics section of readme to include more details on z.ZodTypeAny usage by @braden-w in #3321
- Fix small typos by @mmorearty in #3336
- docs: update Chinese docs and correct some of the typos by @jiechen257 in #3338
- docs: improve chinese readme by @luckrnx09 in #3371
- Add java-to-zod in X to Zod section by @ivangreene in #3385
- docs: add
orval
to "X to Zod" ecosystems by @soartec-lab in #3397
New Contributors
- @jlarmstrongiv made their first contribution in #2949
- @Ansh101112 made their first contribution in #2955
- @NWYLZW made their first contribution in #2988
- @alexnault made their first contribution in #3003
- @shaharke made their first contribution in #3044
- @rbuetzer made their first contribution in #3067
- @schalkventer made their first contribution in #3113
- @evertdespiegeleer made their first contribution in #3134
- @RashJrEdmund made their first contribution in #3181
- @alexmarqs made their first contribution in #3200
- @JonnyBurger made their first contribution in #3214
- @fernandollisboa made their first contribution in #3178
- @g1eny0ung made their first contribution in #3238
- @m10rten made their first contribution in #3278
- @MatthijsMud made their first contribution in #3247
- @yugmade13 made their first contribution in #3317
- @braden-w made their first contribution in #3321
- @mmorearty made their first contribution in #3336
- @schicks made their first contribution in #3295
- @yukukotani made their first contribution in #2912
- @jiechen257 made their first contribution in #3338
- @luckrnx09 made their first contribution in #3371
- @dvv made their first contribution in #3063
- @rotu made their first contribution in #3038
- @petrovmiroslav made their first contribution in #3255
- @ivoilic made their first contribution in #2364
- @telemakhos made their first contribution in #3388...
v3.23.0-beta.0
Zod 3.23 is now in beta! This is the final 3.x
release before Zod 4.0. To try it out:
npm install zod@beta
Features
z.string().date()
Zod can now validate ISO 8601 date strings. Thanks @igalklebanov! #1766
const schema = z.string().date();
schema.parse("2022-01-01"); // OK
z.string().time()
Zod can now validate ISO 8601 time strings. Thanks @igalklebanov! #1766
const schema = z.string().time();
schema.parse("12:00:00"); // OK
You can specify sub-second precision using the precision
option:
const schema = z.string().time({ precision: 3 });
schema.parse("12:00:00.123"); // OK
schema.parse("12:00:00.123456"); // Error
schema.parse("12:00:00"); // Error
z.string().duration()
Zod can now validate ISO 8601 duration strings. Thanks @mastermatt! #3265
const schema = z.string().duration();
schema.parse("P3Y6M4DT12H30M5S"); // OK
Improvements to z.string().datetime()
You can now allow unqualified (timezone-less) datetimes using the local: true
flag.
const schema = z.string().datetime({ local: true });
schema.parse("2022-01-01T12:00:00"); // OK
Plus, Zod now validates the day-of-month correctly to ensure no invalid dates (e.g. February 30th) pass validation. Thanks @szamanr! #3391
z.string().base64()
Zod can now validate base64 strings. Thanks @StefanTerdell! #3047
const schema = z.string().base64();
schema.parse("SGVsbG8gV29ybGQ="); // OK
Improved discriminated unions
The following can now be used as discriminator keys in z.discriminatedUnion()
:
ZodOptional
ZodNullable
ZodReadonly
ZodBranded
ZodCatch
const schema = z.discriminatedUnion("type", [
z.object({ type: z.literal("A").optional(), value: z.number() }),
z.object({ type: z.literal("B").nullable(), value: z.string() }),
z.object({ type: z.literal("C").readonly(), value: z.boolean() }),
z.object({ type: z.literal("D").readonly(), value: z.boolean() }),
z.object({ type: z.literal("E").catch("E"), value: z.unknown() }),
]);
Misc
- feature: allow falsy error message by @fernandollisboa in #3178
- feature: add attribute message to enum validatiion by @fernandollisboa in #3169
Breaking changes
There are no breaking changes to the public API of Zod. However some changes can impact ecosystem tools that rely on Zod internals.
ZodFirstPartySchemaTypes
Three new types have been added to the ZodFirstPartySchemaTypes
union. This may impact some codegen libraries. #3247
+ | ZodPipeline<any, any>
+ | ZodReadonly<any>
+ | ZodSymbol;
Default generics in ZodType
The third argument of the ZodType
base class now defaults to unknown
. This makes it easier to define recursive schemas and write generic functions that accept Zod schemas.
- class ZodType<Output = any, Def extends ZodTypeDef = ZodTypeDef, Input = Output> {}
+ class ZodType<Output = unknown, Def extends ZodTypeDef = ZodTypeDef, Input = unknown> {}
Unrecognized keys in .pick()
and .omit()
This version fixes a bug where unknown keys were accidentally accepted in .pick()
and omit()
. This has been fixed, which could cause compiler errors in some user code. #3255
z.object({
name: z.string()
}).pick({
notAKey: true // no longer allowed
})
Bugfixes and performance
- Bugfix: Enum.extract/exclude should not remove error mapping by @shaharke in #3240
- Added latest stable Node and TypeScript versions to test matrix for up-to-date testing. by @m10rten in #3278
- Add types to
ZodFirstPartySchemaTypes
by @MatthijsMud in #3247 - fix: make
input
of.required()
readonly by @KATT in #3301 - add never props to safe parse return types by @schicks in #3295
- Reporting errors of the preprocess that is the second property of object by @yukukotani in #2912
- Improve
addQuestionMarks
, fix #2184 by @colinhacks in #3352 - fix for njs by @dvv in #3063
- only look in
src
forbun test
by @rotu in #3038 - Restrict .pick()/.omit() mask type to only known properties by @petrovmiroslav in #3255
- Make EnumValues generic by @IlyaSemenov in #2338
- perf: avoid unnecessary error maps by @xuxucode in #2532
- Bugfix: z.record().parse should not filter out undefined values by @raik-casimiro in #3251
- Use Set.has instead of Array.indexOf for enum comparison (perf improvement) by @jmike in #2659
- [2888] fix emails with single quotes failing validation by @Mansehej in #2889
- Bugfix: Commas are incorrectly allowed in email regex. by @mokemoko in #3286
- Fix regex in cuid2 validation to be what cuid2 library expects by @etareduction in #2961
- Make depcruise pass by @rotu in #3037
- Faster ipv4 parsing by @colinhacks in #3413
Docs and ecosystem
- chore: add pastel package to ecosystem by @jlarmstrongiv in #2949
- added required styles. by @Ansh101112 in #2955
- Feature/better chinese translate by @NWYLZW in #2988
- Fix z.instanceof example by @alexnault in #3003
- Add documentation to Zod enum exclude/extract functions by @shaharke in #3044
- Add docs for coercing nullish values by @rbuetzer in #3067
- Adds
zod-dev
utility to eco-system section by @schalkventer in #3113 - Add zhttp library to docs by @evertdespiegeleer in #3134
- fixed Readme typo in NaNs example by @RashJrEdmund in #3181
- adds zod-config library to the ecosystem by @alexmarqs in #3200
- docs: update link and description of conform integration by @g1eny0ung in #3238
- Update README.md by @yugmade13 in #3317
- feat: overhaul generics section of readme to include more details on z.ZodTypeAny usage by @braden-w in #3321
- Fix small typos by @mmorearty in #3336
- docs: update Chinese docs and correct some of the typos by @jiechen257 in #3338
- docs: improve chinese readme by @luckrnx09 in #3371
- Add java-to-zod in X to Zod section by @ivangreene in #3385
- docs: add
orval
to "X to Zod" ecosystems by @soartec-lab in #3397
New Contributors
- @jlarmstrongiv made their first contribution in #2949
- @Ansh101112 made their first contribution in #2955
- @NWYLZW made their first contribution in #2988
- @alexnault made their first contribution in #3003
- @shaharke made their first contribution in #3044
- @rbuetzer made their first contribution in #3067
- @schalkventer made their first contribution in #3113
- @evertdespiegeleer made their first contribution in #3134
- @RashJrEdmund made their first contribution in #3181
- @alexmarqs made their first contribution in #3200
- @JonnyBurger made their first contribution in #3214
- @fernandollisboa made their first contribution in #3178
- @g1eny0ung made their first contribution in #3238
- @m10rten made their first contribution in #3278
- @MatthijsMud made their first contribution in #3247
- @yugmade13 made their first contribution in #3317
- @braden-w made their first contribution in #3321
- @mmorearty made their first contribution in #3336
- @schicks made their first contribution in #3295
- @yukukotani made their first contribution in #2912
- @jiechen257 made their first contribution in #3338
- @luckrnx09 made their first contribution in #3371
- @dvv made their first contribut...
v3.22.4
Commits:
- d931ea3 Lint
- 8e634bd Fix prettier
- 4018d88 docs: add @sanity-typed/zod to ecosystem (#2731)
- 15ba5a4 docs: add
zod-sandbox
to README ecosystem links (#2707) - 699ccae Export jsdoc with
@deprecated
when building (#2717) - dfe3719 Fix sanity-typed links (#2840)
- cd7991e fix ulid regex (#2225)
- 7cb4ba2 Remove stalebot
- 9340fd5 Lazy emojiRegex
- e7a9b9b 3.22.4
v3.22.3
Commits:
- 1e23990 Commit
- 9bd3879 docs: remove obsolete text about readonly types (#2676)
- f59be09 clarify datetime ISO 8601 (#2673)
- 64dcc8e Update sponsors
- 18115a8 Formatting
- 28c1927 Update sponsors
- ad2ee9c 2718 Updated Custom Schemas documentation example to use type narrowing (#2778)
- ae0f7a2 docs: update ref to discriminated-unions docs (#2485)
- 2ba00fe [2609] fix ReDoS vulnerability in email regex (#2824)
- 1e61d76 3.22.3
v3.22.2
v3.22.1
Commits:
Fix handing of this
in ZodFunction schemas. The parse logic for function schemas now requires the Reflect
API.
const methodObject = z.object({
property: z.number(),
method: z.function().args(z.string()).returns(z.number()),
});
const methodInstance = {
property: 3,
method: function (s: string) {
return s.length + this.property;
},
};
const parsed = methodObject.parse(methodInstance);
parsed.method("length=8"); // => 11 (8 length + 3 property)
v3.22.0
ZodReadonly
This release introduces ZodReadonly
and the .readonly()
method on ZodType
.
Calling .readonly()
on any schema returns a ZodReadonly
instance that wraps the original schema. The new schema parses all inputs using the original schema, then calls Object.freeze()
on the result. The inferred type is also marked as readonly
.
const schema = z.object({ name: string }).readonly();
type schema = z.infer<typeof schema>;
// Readonly<{name: string}>
const result = schema.parse({ name: "fido" });
result.name = "simba"; // error
The inferred type uses TypeScript's built-in readonly types when relevant.
z.array(z.string()).readonly();
// readonly string[]
z.tuple([z.string(), z.number()]).readonly();
// readonly [string, number]
z.map(z.string(), z.date()).readonly();
// ReadonlyMap<string, Date>
z.set(z.string()).readonly();
// ReadonlySet<Promise<string>>
Commits:
- 6dad907 Comments
- 56ace68 Fix deno test
- 3809d54 Add superforms
- d1ad522 Add transloadit
- a3bb701 Testing on Typescript 5.0 (#2221)
- 51e14be docs: update deprecated link (#2219)
- a263814 fixed Datetime & IP TOC links
- 502384e docs: add mobx-zod-form to form integrations (#2299)
- a8be450 docs: Add
zocker
to Ecosystem section (#2416) - 15de22a Allow subdomains and hyphens in
ZodString.email
(#2274) - 00f5783 Add
zod-openapi
to ecosystem (#2434) - 0a17340 docs: fix minor typo (#2439)
- 60a2134 Add masterborn
- 0a90ed1 chore: move
exports.types
field to first spot @ package.json. (#2443) - 67f35b1 docs: allow Zod to be used in dev tools at site (#2432)
- 6795c57 Fix not working Deno doc link. (#2428)
- 37e9c55 Generalize uuidRegex
- 0969950 adds ctx to preprocess (#2426)
- af08390 fix: super refinement function types (#2420)
- 36fef58 Make email regex reasonable (#2157)
- f627d14 Document canary
- e06321c docs: add tapiduck to API libraries (#2410)
- 11e507c docs: add ts as const example in zod enums (#2412)
- 5427565 docs: add zod-fixture to mocking ecosystem (#2409)
- d3bf7e6 docs: add
zodock
to mocking ecosystem (#2394) - 2270ae5 remove "as any" casts in createZodEnum (#2332)
- 00bdd0a fix proto pollution vulnerability (#2239)
- a3c5256 Fix error_handling unrecognized_keys example
- 4f75cbc Adds getters to Map for key + value (#2356)
- ca7b032 FMC (#2346)
- 6fec8bd docs: fix typo in link fragment (#2329)
- 16f90bd Update README.md
- 2c80250 Update readme
- eaf64e0 Update sponsors
- c576311 Update readme
- 5e23b4f Add
*.md
pattern to prettier (#2476) - 898dced Revamp tests
- 6309322 Update test runners
- c0aece1 Add vitest config
- 73a5610 Update script
- 8d8e1a2 Fix deno test bug
- 9eb2508 Clean up configs
- cfbc7b3 Fix root jest config
- 8677f68 docs(comparison-yup): Yup added partial() and deepPartial() in v1 (#2603)
- fb00edd docs: add VeeValidate form library for Vue.js (#2578)
- ab8e717 docs: fix typo in z.object (#2570)
- d870407 docs: fix incomplete Records example (#2579)
- 5adae24 docs: add conform form integration (#2577)
- 8b8ab3e Update README.md (#2562)
- 6aab901 fix typo test name (#2542)
- 81a89f5 Update nullish documentation to correct chaining order (#2457)
- 78a4090 docs: update comparison with
runtypes
(#2536) - 1ecd624 Fix prettier
- 981d4b5 Add ZodReadonly (#2634)
- fba438c 3.22.0