Skip to content

Commit 11477ae

Browse files
committed
Add test
1 parent c00ca42 commit 11477ae

File tree

3 files changed

+68
-38
lines changed

3 files changed

+68
-38
lines changed

packages/zod/src/v4/classic/tests/error-utils.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,3 +478,50 @@ test("inheritance", () => {
478478
expect(e2).toBeInstanceOf(z.ZodRealError);
479479
expect(e2).toBeInstanceOf(Error);
480480
});
481+
482+
test("disc union treeify/format", () => {
483+
const schema = z.discriminatedUnion(
484+
"foo",
485+
[
486+
z.object({
487+
foo: z.literal("x"),
488+
x: z.string(),
489+
}),
490+
z.object({
491+
foo: z.literal("y"),
492+
y: z.string(),
493+
}),
494+
],
495+
{
496+
error: "Invalid discriminator",
497+
}
498+
);
499+
500+
const error = schema.safeParse({ foo: "invalid" }).error;
501+
expect(z.treeifyError(error!)).toMatchInlineSnapshot(`
502+
{
503+
"errors": [],
504+
"properties": {
505+
"foo": {
506+
"errors": [
507+
"Invalid discriminator",
508+
],
509+
},
510+
},
511+
}
512+
`);
513+
expect(z.prettifyError(error!)).toMatchInlineSnapshot(`
514+
"✖ Invalid discriminator
515+
→ at foo"
516+
`);
517+
expect(z.formatError(error!)).toMatchInlineSnapshot(`
518+
{
519+
"_errors": [],
520+
"foo": {
521+
"_errors": [
522+
"Invalid discriminator",
523+
],
524+
},
525+
}
526+
`);
527+
});

packages/zod/src/v4/core/errors.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ export function formatError<T>(error: $ZodError, _mapper?: any) {
255255
const fieldErrors: $ZodFormattedError<T> = { _errors: [] } as any;
256256
const processError = (error: { issues: $ZodIssue[] }) => {
257257
for (const issue of error.issues) {
258-
if (issue.code === "invalid_union") {
258+
if (issue.code === "invalid_union" && issue.errors.length) {
259259
issue.errors.map((issues) => processError({ issues }));
260260
} else if (issue.code === "invalid_key") {
261261
processError({ issues: issue.issues });
@@ -306,7 +306,8 @@ export function treeifyError<T>(error: $ZodError, _mapper?: any) {
306306
const result: $ZodErrorTree<T> = { errors: [] } as any;
307307
const processError = (error: { issues: $ZodIssue[] }, path: PropertyKey[] = []) => {
308308
for (const issue of error.issues) {
309-
if (issue.code === "invalid_union") {
309+
if (issue.code === "invalid_union" && issue.errors.length) {
310+
// regular union error
310311
issue.errors.map((issues) => processError({ issues }, issue.path));
311312
} else if (issue.code === "invalid_key") {
312313
processError({ issues: issue.issues }, issue.path);

play.ts

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,22 @@
11
import { z } from "zod/v4";
22

3-
const a = z.object({
4-
name: z.string(),
5-
age: z.number().int().positive(),
6-
});
7-
8-
console.dir(
9-
z.toJSONSchema(a, {
10-
override(ctx) {
11-
const schema = ctx.zodSchema;
12-
if (schema instanceof z.core.$ZodObject && schema._zod.def.catchall === undefined) {
13-
delete ctx.jsonSchema.additionalProperties;
14-
}
15-
},
16-
}),
17-
{ depth: null }
3+
const schema = z.discriminatedUnion(
4+
"foo",
5+
[
6+
z.object({
7+
foo: z.literal("x"),
8+
x: z.string(),
9+
}),
10+
z.object({
11+
foo: z.literal("y"),
12+
y: z.string(),
13+
}),
14+
],
15+
{
16+
error: "Invalid discriminator",
17+
}
1818
);
1919

20-
const arg = z.string().safeParse("hello"); // should not throw
21-
z.treeifyError(arg.error!);
22-
23-
// import { z } from "zod/v4";
24-
25-
const output = z.string();
26-
27-
const aa = z.function();
28-
type aa = Parameters<typeof aa._output>;
29-
30-
const itWorks = z.function({ input: [z.string()] }).implement(output.parse);
31-
const itWorks2 = z.function({ input: [z.string()] }).implement((args) => output.parse(args));
32-
const itWorks3 = z.function({ input: [z.string().default("")] }).implement(output.parse);
33-
const itWorks4 = z.function({ input: [z.string()] }).implement((args) => output.parse(args));
34-
const nope = z.function({ input: [z.string().default("")] }).implement((args) => output.parse(args));
35-
36-
type ItWorks = ReturnType<typeof itWorks>;
37-
type ItWorks2 = ReturnType<typeof itWorks2>;
38-
type ItWorks3 = ReturnType<typeof itWorks3>;
39-
type ItWorks4 = ReturnType<typeof itWorks4>;
40-
type Nope = ReturnType<typeof nope>; //unknown
20+
const error = schema.safeParse({ foo: "invalid" }).error;
21+
console.log("error:", error);
22+
console.dir(z.treeifyError(error!), { depth: null });

0 commit comments

Comments
 (0)