Skip to content

feat: add exactOptional option for zod and effect generators - #3739

Merged
melloware merged 1 commit into
orval-labs:masterfrom
MayCXC:feat/exact-optional
Jul 17, 2026
Merged

feat: add exactOptional option for zod and effect generators#3739
melloware merged 1 commit into
orval-labs:masterfrom
MayCXC:feat/exact-optional

Conversation

@MayCXC

@MayCXC MayCXC commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes #3738.

Optional object properties emit .optional() (zod) / S.optional() (effect), inferring { x?: T | undefined }, which TS2375s against an exact-optional interface under exactOptionalPropertyTypes.

Adds an opt-in override.zod.exactOptional / override.effect.exactOptional (default false, so existing output is unchanged), mirroring generateMeta:

  • zod v4 classic -> .exactOptional(), mini -> zod.exactOptional()
  • effect -> S.optionalWith(schema, { exact: true })
  • zod v3 -> no-op (.exactOptional() does not exist there)
  • only .optional() is narrowed; .nullish() (which admits undefined, legal under the flag) is left unchanged in both generators

Threaded through the reusable-schema / standalone-zod paths so it also applies in generateReusableSchemas mode. Tests cover classic/mini/v3/nullish, the reusable-schema path, and the normalizer. Default-off output is byte-identical; the full typecheck and the zod/effect/orval package suites pass.

Summary by CodeRabbit

  • New Features

    • Added an opt-in exactOptional setting for Zod v4 and Effect schema generation.
    • Optional properties can now preserve exact TypeScript optional-property semantics.
    • Applies consistently to request parameters, request bodies, responses, and reusable schemas.
    • Zod Mini is supported; Zod v3 remains unchanged.
  • Documentation

    • Expanded configuration guidance and clarified that these settings are valid only under the appropriate output overrides.
    • Documented ignored settings and build warnings when configured at unsupported levels.

Optional object properties emit `.optional()` (zod) / `S.optional()` (effect),
which infer `{ x?: T | undefined }`. Consumers compiling with
exactOptionalPropertyTypes cannot import the generated schemas' inferred types
without a TS2375 mismatch against their exact-optional interfaces.

Add opt-in `override.zod.exactOptional` / `override.effect.exactOptional`
(default false, so existing output is unchanged) that emits, for optional
properties:

- zod v4 classic: `.exactOptional()`
- zod v4 mini: `zod.exactOptional()`
- effect: `S.optionalWith(schema, { exact: true })`

so those consumers infer `{ x?: T }`. zod v3 has no `.exactOptional()`, so the
flag no-ops there. Only `.optional()` is narrowed; `.nullish()` intentionally
admits undefined (legal under exactOptionalPropertyTypes) and is unchanged in
both generators.
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 17805460-4df6-445f-aa98-822eba9386bc

📥 Commits

Reviewing files that changed from the base of the PR and between 793fe53 and 4fc3291.

📒 Files selected for processing (17)
  • docs/content/docs/guides/zod.mdx
  • docs/content/docs/reference/configuration/output.mdx
  • packages/angular/src/http-client.test.ts
  • packages/angular/src/http-resource.test.ts
  • packages/core/src/test-utils/context.ts
  • packages/core/src/types.ts
  • packages/effect/src/effect.test.ts
  • packages/effect/src/index.ts
  • packages/mock/src/faker/getters/combine.test.ts
  • packages/orval/src/reusable-schemas.test.ts
  • packages/orval/src/reusable-schemas.ts
  • packages/orval/src/utils/options.test.ts
  • packages/orval/src/utils/options.ts
  • packages/orval/src/write-zod-specs.ts
  • packages/solid-start/src/index.test.ts
  • packages/zod/src/index.ts
  • packages/zod/src/zod.test.ts

📝 Walkthrough

Walkthrough

Adds opt-in exactOptional settings for Zod and Effect generation. The option is normalized, propagated through inline and reusable schema paths, emits Zod v4 and Effect exact-optional APIs, preserves existing defaults, and is covered by tests and documentation.

Changes

Exact optional schema generation

Layer / File(s) Summary
Configuration and normalization contract
packages/core/src/types.ts, packages/orval/src/utils/options.ts, packages/orval/src/write-zod-specs.ts
Adds exactOptional to Zod and Effect option types, normalized configurations, and Zod output configuration.
Zod exact-optional generation
packages/zod/src/index.ts, packages/orval/src/reusable-schemas.ts, packages/orval/src/write-zod-specs.ts
Propagates the option through route, inline, reusable, and verb-based generation; Zod v4 emits exact-optional APIs while Zod v3 remains unchanged.
Effect exact-optional generation
packages/effect/src/index.ts, packages/effect/src/effect.test.ts
Propagates the option across request and response schemas and emits S.optionalWith(..., { exact: true }) for optional properties.
Validation, defaults, and documentation
packages/zod/src/zod.test.ts, packages/orval/src/reusable-schemas.test.ts, packages/orval/src/utils/options.test.ts, packages/angular/src/*, packages/core/src/test-utils/context.ts, packages/mock/src/faker/getters/combine.test.ts, packages/solid-start/src/index.test.ts, docs/content/docs/...
Tests exact-optional behavior and normalization, updates default test configurations, and documents Zod and Effect settings.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: enhancement, zod

Suggested reviewers: aqeelat, arthurfiorette, melloware

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the new exactOptional option for Zod and Effect generators.
Linked Issues check ✅ Passed The changes add opt-in exactOptional support across types, normalization, generators, reusable schemas, tests, and docs as requested.
Out of Scope Changes check ✅ Passed The diff stays focused on exactOptional support and related tests/docs, with no obvious unrelated feature work.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@melloware melloware added the zod Zod schema client related issue label Jul 17, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jul 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

@orval/angular

bun add https://pkg.pr.new/@orval/angular@4fc3291

@orval/axios

bun add https://pkg.pr.new/@orval/axios@4fc3291

@orval/core

bun add https://pkg.pr.new/@orval/core@4fc3291

@orval/effect

bun add https://pkg.pr.new/@orval/effect@4fc3291

@orval/fetch

bun add https://pkg.pr.new/@orval/fetch@4fc3291

@orval/hono

bun add https://pkg.pr.new/@orval/hono@4fc3291

@orval/mcp

bun add https://pkg.pr.new/@orval/mcp@4fc3291

@orval/mock

bun add https://pkg.pr.new/@orval/mock@4fc3291

orval

bun add https://pkg.pr.new/orval@4fc3291

@orval/query

bun add https://pkg.pr.new/@orval/query@4fc3291

@orval/solid-start

bun add https://pkg.pr.new/@orval/solid-start@4fc3291

@orval/swr

bun add https://pkg.pr.new/@orval/swr@4fc3291

@orval/zod

bun add https://pkg.pr.new/@orval/zod@4fc3291

commit: 4fc3291

@melloware
melloware merged commit dda0726 into orval-labs:master Jul 17, 2026
7 checks passed
MayCXC added a commit to MayCXC/maycxc.github.io that referenced this pull request Jul 17, 2026
The exactOptional PR (orval-labs/orval#3739) is merged; add it to the contributions list.

Forked repos are excluded from the GitHub search/repositories API by default, so vlasky/sqlite-vec
never returned in the counts fetch and stayed "? forks, ? stars". Adding fork:true to the query
includes forks alongside non-forks, so it fills like the rest.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

zod Zod schema client related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option to emit exact-optional properties for exactOptionalPropertyTypes (zod + effect)

2 participants