feat: allow 'when' parameter in .superRefine#5741
Conversation
|
@vilvai is attempting to deploy a commit to the colinhacks Team on Vercel. A member of the Team first needs to authorize it. |
|
TL;DR — Adds an optional Key changes
Summary | 5 files | 2 commits | base:
The new
|
28782de to
afc91d1
Compare
There was a problem hiding this comment.
Important
The JSDoc on $ZodSuperRefineParams.when describes the default behavior incorrectly — worth fixing before merge.
- Added
$ZodSuperRefineParamsinterface with awhenoption and threaded it through_superRefine→_checkin both classic and mini APIs - Added two tests covering the
when: () => true(superRefine runs despite base schema failure) andwhen: () => false(superRefine skipped) cases
Claude Opus | 𝕏
| * `when` — whether to run the refinement at all. | ||
| */ | ||
| export interface $ZodSuperRefineParams { | ||
| /** If provided, this refinement will only be executed if the function returns `true`. Defaults to `payload => z.util.isAborted(payload)`. */ |
There was a problem hiding this comment.
The JSDoc says the default is payload => z.util.isAborted(payload), but the actual default behavior (when when is omitted) is to skip the check when the payload is aborted — effectively the opposite. Additionally, z.util.isAborted doesn't exist in v4; the internal helper is util.aborted.
Note: this same misleading JSDoc exists on $ZodCheckDef.when in checks.ts:16, so it's a pre-existing issue that was copied here. Still, it would be good to fix it in this PR since it's in newly added code.
Suggested wording:
/** If provided, this refinement will only be executed when the function returns `true`. When omitted, the refinement is skipped if the base schema produced any aborting issues. */
| /** If provided, this refinement will only be executed if the function returns `true`. Defaults to `payload => z.util.isAborted(payload)`. */ | |
| /** If provided, this refinement will only be executed when the function returns `true`. When omitted, the refinement is skipped if the base schema produced any aborting issues. */ |
The previous `string | $ZodCustomParams` type advertised fields that don't do anything useful for `.superRefine` — `error`/`message`/`path` are never read because the refinement pushes its own issues via `ctx.addIssue`, and `abort` is redundant with the per-issue `fatal` flag (which sets `continue: false` directly on the issue, with finer granularity than a check-level toggle). Introduce a dedicated `$ZodSuperRefineParams` interface exposing only `when` — the one execution-control option that genuinely gates whether the refinement runs at all. Also wire `params` through in `mini` for parity.
There was a problem hiding this comment.
No new issues. Reviewed the following changes:
- Fixed the JSDoc on
$ZodSuperRefineParams.whento accurately describe the default behavior - Fixed the same misleading JSDoc on
$ZodCheckDef.wheninchecks.ts(the pre-existing issue flagged in the prior review) - Removed the verbose block comment on the
$ZodSuperRefineParamsinterface
Prior review feedback:
- JSDoc on
$ZodSuperRefineParams.whendescribes default behavior incorrectly — addressed (also fixed in$ZodCheckDef.when)
Claude Opus | 𝕏
There was a problem hiding this comment.
Approving — prior JSDoc feedback was fully addressed and no new issues found.
Claude Opus | 𝕏
|
Narrowed the Note: this comment was produced by an AI coding assistant. |
|
Landed in Zod 4.4 |
This PR adds the
paramsobject to.superRefinewhich allows usingwhenparameter to run the superrefine validation even when the base schema fails, similar to how.refineworks currentlySee my issue about this: #5739