diff --git a/deno/lib/__tests__/refine.test.ts b/deno/lib/__tests__/refine.test.ts index 07b380c14..f505fdbb7 100644 --- a/deno/lib/__tests__/refine.test.ts +++ b/deno/lib/__tests__/refine.test.ts @@ -156,6 +156,35 @@ test("superRefine", () => { Strings.parse(["asfd", "qwer"]); }); +test("superRefine async", async () => { + const Strings = z.array(z.string()).superRefine(async (val, ctx) => { + if (val.length > 3) { + ctx.addIssue({ + code: z.ZodIssueCode.too_big, + maximum: 3, + type: "array", + inclusive: true, + exact: true, + message: "Too many items 😡", + }); + } + + if (val.length !== new Set(val).size) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `No duplicates allowed.`, + }); + } + }); + + const result = await Strings.safeParseAsync(["asfd", "asfd", "asfd", "asfd"]); + + expect(result.success).toEqual(false); + if (!result.success) expect(result.error.issues.length).toEqual(2); + + Strings.parseAsync(["asfd", "qwer"]); +}); + test("superRefine - type narrowing", () => { type NarrowType = { type: string; age: number }; const schema = z diff --git a/deno/lib/types.ts b/deno/lib/types.ts index 3e9e686f8..3a429979d 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -371,10 +371,10 @@ export abstract class ZodType< refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput ): ZodEffects; superRefine( - refinement: (arg: Output, ctx: RefinementCtx) => void + refinement: (arg: Output, ctx: RefinementCtx) => void | Promise ): ZodEffects; superRefine( - refinement: (arg: Output, ctx: RefinementCtx) => unknown + refinement: (arg: Output, ctx: RefinementCtx) => unknown | Promise ): ZodEffects { return this._refinement(refinement); } @@ -4174,7 +4174,7 @@ export class ZodPromise extends ZodType< ////////////////////////////////////////////// export type Refinement = (arg: T, ctx: RefinementCtx) => any; -export type SuperRefinement = (arg: T, ctx: RefinementCtx) => void; +export type SuperRefinement = (arg: T, ctx: RefinementCtx) => void | Promise; export type RefinementEffect = { type: "refinement"; diff --git a/src/__tests__/refine.test.ts b/src/__tests__/refine.test.ts index 98036c73f..4d03439ba 100644 --- a/src/__tests__/refine.test.ts +++ b/src/__tests__/refine.test.ts @@ -155,6 +155,35 @@ test("superRefine", () => { Strings.parse(["asfd", "qwer"]); }); +test("superRefine async", async () => { + const Strings = z.array(z.string()).superRefine(async (val, ctx) => { + if (val.length > 3) { + ctx.addIssue({ + code: z.ZodIssueCode.too_big, + maximum: 3, + type: "array", + inclusive: true, + exact: true, + message: "Too many items 😡", + }); + } + + if (val.length !== new Set(val).size) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: `No duplicates allowed.`, + }); + } + }); + + const result = await Strings.safeParseAsync(["asfd", "asfd", "asfd", "asfd"]); + + expect(result.success).toEqual(false); + if (!result.success) expect(result.error.issues.length).toEqual(2); + + Strings.parseAsync(["asfd", "qwer"]); +}); + test("superRefine - type narrowing", () => { type NarrowType = { type: string; age: number }; const schema = z diff --git a/src/types.ts b/src/types.ts index 537e361f0..59252e867 100644 --- a/src/types.ts +++ b/src/types.ts @@ -371,10 +371,10 @@ export abstract class ZodType< refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput ): ZodEffects; superRefine( - refinement: (arg: Output, ctx: RefinementCtx) => void + refinement: (arg: Output, ctx: RefinementCtx) => void | Promise ): ZodEffects; superRefine( - refinement: (arg: Output, ctx: RefinementCtx) => unknown + refinement: (arg: Output, ctx: RefinementCtx) => unknown | Promise ): ZodEffects { return this._refinement(refinement); } @@ -4174,7 +4174,7 @@ export class ZodPromise extends ZodType< ////////////////////////////////////////////// export type Refinement = (arg: T, ctx: RefinementCtx) => any; -export type SuperRefinement = (arg: T, ctx: RefinementCtx) => void; +export type SuperRefinement = (arg: T, ctx: RefinementCtx) => void | Promise; export type RefinementEffect = { type: "refinement";