diff --git a/deno/lib/types.ts b/deno/lib/types.ts index eec0e4259..61d277eab 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -318,6 +318,7 @@ export abstract class ZodType< constructor(def: Def) { this._def = def; this.transform = this.transform.bind(this) as any; + this.refineWith = this.refineWith.bind(this) as any; this.default = this.default.bind(this); } @@ -359,6 +360,30 @@ export abstract class ZodType< return returnType; } + refineWith( + returnType: ZodType + ): This extends ZodEffects + ? ZodEffects + : ZodEffects { + let parsed: ReturnType; + const refined: ZodEffects = this._refinement((val, ctx) => { + parsed = returnType.safeParse(val); + if (!parsed.success) { + for (const issue of parsed.error.issues) { + ctx.addIssue(issue); + } + } + }); + + return refined.transform(() => { + if (!parsed.success) { + throw new Error(`Unreachable path.`); + } + + return parsed.data; + }) as any; + } + default( def: T ): ZodOptional; diff --git a/src/types.ts b/src/types.ts index bca6361e2..a940dad12 100644 --- a/src/types.ts +++ b/src/types.ts @@ -318,6 +318,7 @@ export abstract class ZodType< constructor(def: Def) { this._def = def; this.transform = this.transform.bind(this) as any; + this.refineWith = this.refineWith.bind(this) as any; this.default = this.default.bind(this); } @@ -359,6 +360,30 @@ export abstract class ZodType< return returnType; } + refineWith( + returnType: ZodType + ): This extends ZodEffects + ? ZodEffects + : ZodEffects { + let parsed: ReturnType; + const refined: ZodEffects = this._refinement((val, ctx) => { + parsed = returnType.safeParse(val); + if (!parsed.success) { + for (const issue of parsed.error.issues) { + ctx.addIssue(issue); + } + } + }); + + return refined.transform(() => { + if (!parsed.success) { + throw new Error(`Unreachable path.`); + } + + return parsed.data; + }) as any; + } + default( def: T ): ZodOptional;