diff --git a/coverage.svg b/coverage.svg
index 16e49a97b..66a0c9f15 100644
--- a/coverage.svg
+++ b/coverage.svg
@@ -1 +1,5 @@
-
\ No newline at end of file
+<<<<<<< HEAD
+
+=======
+
+>>>>>>> 3b6802c (Fast unions)
diff --git a/deno/lib/types.ts b/deno/lib/types.ts
index caf9c014b..bec55020f 100644
--- a/deno/lib/types.ts
+++ b/deno/lib/types.ts
@@ -2,6 +2,7 @@ import { errorUtil } from "./helpers/errorUtil.ts";
import {
addIssueToContext,
AsyncParseReturnType,
+ DIRTY,
getParsedType,
INVALID,
isAborted,
@@ -1849,6 +1850,7 @@ export class ZodUnion extends ZodType<
const unionErrors = results.map(
(result) => new ZodError(result.ctx.issues)
);
+
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union,
unionErrors,
@@ -1875,23 +1877,44 @@ export class ZodUnion extends ZodType<
})
).then(handleResults);
} else {
- const optionResults = options.map((option) => {
+ let dirty: undefined | { result: DIRTY; ctx: ParseContext } =
+ undefined;
+ const issues: ZodIssue[][] = [];
+ for (const option of options) {
const childCtx: ParseContext = {
...ctx,
issues: [],
parent: null,
};
- return {
- result: option._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: childCtx,
- }),
- ctx: childCtx,
- };
+ const result = option._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: childCtx,
+ });
+
+ if (result.status === "valid") {
+ return result;
+ } else if (result.status === "dirty" && !dirty) {
+ dirty = { result, ctx: childCtx };
+ }
+
+ if (childCtx.issues.length) {
+ issues.push(childCtx.issues);
+ }
+ }
+
+ if (dirty) {
+ ctx.issues.push(...dirty.ctx.issues);
+ return dirty.result;
+ }
+
+ const unionErrors = issues.map((issues) => new ZodError(issues));
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_union,
+ unionErrors,
});
- return handleResults(optionResults);
+ return INVALID;
}
}
diff --git a/src/types.ts b/src/types.ts
index b3b7c1df2..29db38b2a 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -2,6 +2,7 @@ import { errorUtil } from "./helpers/errorUtil";
import {
addIssueToContext,
AsyncParseReturnType,
+ DIRTY,
getParsedType,
INVALID,
isAborted,
@@ -1849,6 +1850,7 @@ export class ZodUnion extends ZodType<
const unionErrors = results.map(
(result) => new ZodError(result.ctx.issues)
);
+
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union,
unionErrors,
@@ -1875,23 +1877,44 @@ export class ZodUnion extends ZodType<
})
).then(handleResults);
} else {
- const optionResults = options.map((option) => {
+ let dirty: undefined | { result: DIRTY; ctx: ParseContext } =
+ undefined;
+ const issues: ZodIssue[][] = [];
+ for (const option of options) {
const childCtx: ParseContext = {
...ctx,
issues: [],
parent: null,
};
- return {
- result: option._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: childCtx,
- }),
- ctx: childCtx,
- };
+ const result = option._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: childCtx,
+ });
+
+ if (result.status === "valid") {
+ return result;
+ } else if (result.status === "dirty" && !dirty) {
+ dirty = { result, ctx: childCtx };
+ }
+
+ if (childCtx.issues.length) {
+ issues.push(childCtx.issues);
+ }
+ }
+
+ if (dirty) {
+ ctx.issues.push(...dirty.ctx.issues);
+ return dirty.result;
+ }
+
+ const unionErrors = issues.map((issues) => new ZodError(issues));
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_union,
+ unionErrors,
});
- return handleResults(optionResults);
+ return INVALID;
}
}