Skip to content

Commit af08390

Browse files
fix: super refinement function types (#2420)
* fix: super refinement function types * Add test --------- Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
1 parent 0969950 commit af08390

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

deno/lib/__tests__/refine.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,35 @@ test("superRefine", () => {
156156
Strings.parse(["asfd", "qwer"]);
157157
});
158158

159+
test("superRefine async", async () => {
160+
const Strings = z.array(z.string()).superRefine(async (val, ctx) => {
161+
if (val.length > 3) {
162+
ctx.addIssue({
163+
code: z.ZodIssueCode.too_big,
164+
maximum: 3,
165+
type: "array",
166+
inclusive: true,
167+
exact: true,
168+
message: "Too many items 😡",
169+
});
170+
}
171+
172+
if (val.length !== new Set(val).size) {
173+
ctx.addIssue({
174+
code: z.ZodIssueCode.custom,
175+
message: `No duplicates allowed.`,
176+
});
177+
}
178+
});
179+
180+
const result = await Strings.safeParseAsync(["asfd", "asfd", "asfd", "asfd"]);
181+
182+
expect(result.success).toEqual(false);
183+
if (!result.success) expect(result.error.issues.length).toEqual(2);
184+
185+
Strings.parseAsync(["asfd", "qwer"]);
186+
});
187+
159188
test("superRefine - type narrowing", () => {
160189
type NarrowType = { type: string; age: number };
161190
const schema = z

deno/lib/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,10 @@ export abstract class ZodType<
371371
refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput
372372
): ZodEffects<this, RefinedOutput, Input>;
373373
superRefine(
374-
refinement: (arg: Output, ctx: RefinementCtx) => void
374+
refinement: (arg: Output, ctx: RefinementCtx) => void | Promise<void>
375375
): ZodEffects<this, Output, Input>;
376376
superRefine(
377-
refinement: (arg: Output, ctx: RefinementCtx) => unknown
377+
refinement: (arg: Output, ctx: RefinementCtx) => unknown | Promise<unknown>
378378
): ZodEffects<this, Output, Input> {
379379
return this._refinement(refinement);
380380
}
@@ -4174,7 +4174,7 @@ export class ZodPromise<T extends ZodTypeAny> extends ZodType<
41744174
//////////////////////////////////////////////
41754175

41764176
export type Refinement<T> = (arg: T, ctx: RefinementCtx) => any;
4177-
export type SuperRefinement<T> = (arg: T, ctx: RefinementCtx) => void;
4177+
export type SuperRefinement<T> = (arg: T, ctx: RefinementCtx) => void | Promise<void>;
41784178

41794179
export type RefinementEffect<T> = {
41804180
type: "refinement";

src/__tests__/refine.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,35 @@ test("superRefine", () => {
155155
Strings.parse(["asfd", "qwer"]);
156156
});
157157

158+
test("superRefine async", async () => {
159+
const Strings = z.array(z.string()).superRefine(async (val, ctx) => {
160+
if (val.length > 3) {
161+
ctx.addIssue({
162+
code: z.ZodIssueCode.too_big,
163+
maximum: 3,
164+
type: "array",
165+
inclusive: true,
166+
exact: true,
167+
message: "Too many items 😡",
168+
});
169+
}
170+
171+
if (val.length !== new Set(val).size) {
172+
ctx.addIssue({
173+
code: z.ZodIssueCode.custom,
174+
message: `No duplicates allowed.`,
175+
});
176+
}
177+
});
178+
179+
const result = await Strings.safeParseAsync(["asfd", "asfd", "asfd", "asfd"]);
180+
181+
expect(result.success).toEqual(false);
182+
if (!result.success) expect(result.error.issues.length).toEqual(2);
183+
184+
Strings.parseAsync(["asfd", "qwer"]);
185+
});
186+
158187
test("superRefine - type narrowing", () => {
159188
type NarrowType = { type: string; age: number };
160189
const schema = z

src/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,10 @@ export abstract class ZodType<
371371
refinement: (arg: Output, ctx: RefinementCtx) => arg is RefinedOutput
372372
): ZodEffects<this, RefinedOutput, Input>;
373373
superRefine(
374-
refinement: (arg: Output, ctx: RefinementCtx) => void
374+
refinement: (arg: Output, ctx: RefinementCtx) => void | Promise<void>
375375
): ZodEffects<this, Output, Input>;
376376
superRefine(
377-
refinement: (arg: Output, ctx: RefinementCtx) => unknown
377+
refinement: (arg: Output, ctx: RefinementCtx) => unknown | Promise<unknown>
378378
): ZodEffects<this, Output, Input> {
379379
return this._refinement(refinement);
380380
}
@@ -4174,7 +4174,7 @@ export class ZodPromise<T extends ZodTypeAny> extends ZodType<
41744174
//////////////////////////////////////////////
41754175

41764176
export type Refinement<T> = (arg: T, ctx: RefinementCtx) => any;
4177-
export type SuperRefinement<T> = (arg: T, ctx: RefinementCtx) => void;
4177+
export type SuperRefinement<T> = (arg: T, ctx: RefinementCtx) => void | Promise<void>;
41784178

41794179
export type RefinementEffect<T> = {
41804180
type: "refinement";

0 commit comments

Comments
 (0)