Skip to content

Add useNullish configuration option for Zod to use z.nullish instead of z.optional - closes #2323#3302

Open
hbmartin wants to merge 1 commit intohey-api:mainfrom
hbmartin:zod-nullish
Open

Add useNullish configuration option for Zod to use z.nullish instead of z.optional - closes #2323#3302
hbmartin wants to merge 1 commit intohey-api:mainfrom
hbmartin:zod-nullish

Conversation

@hbmartin
Copy link

@hbmartin hbmartin commented Feb 3, 2026

By default, non-required object properties generate .optional(), which accepts undefined values. Some API's incorrectly use nullable in their specs, where required properties can also be set null. By using this option, the generator produces .nullish() instead of .optional().

See issues:
#2323
#3243

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@vercel
Copy link

vercel bot commented Feb 3, 2026

@hbmartin is attempting to deploy a commit to the Hey API Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot
Copy link

changeset-bot bot commented Feb 3, 2026

⚠️ No Changeset found

Latest commit: 4694719

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. feature 🚀 Feature request. labels Feb 3, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 46947192fe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 144 to +147
if (optional) {
ast.expression = $(z).attr(identifiers.optional).call(ast.expression);
ast.typeName = identifiers.ZodOptional;
const method = plugin.config.useNullish ? identifiers.nullish : identifiers.optional;
ast.expression = $(z).attr(method).call(ast.expression);
ast.typeName = plugin.config.useNullish ? identifiers.ZodNullish : identifiers.ZodOptional;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid referencing non-existent z.ZodNullish type

When useNullish is enabled, this changes the type annotation to z.ZodNullish, but Zod doesn’t expose a ZodNullish type (nullish is a convenience for ZodOptional<ZodNullable<...>>). In v4 outputs that include type annotations, this will cause generated code to fail type checking because z.ZodNullish is undefined. Consider keeping ZodOptional (or omitting the type annotation) when generating .nullish().

Useful? React with 👍 / 👎.

Comment on lines 141 to +146
if (optional) {
ast.expression = $(z).attr(identifiers.optional).call(ast.expression);
ast.typeName = identifiers.ZodMiniOptional;
const method = plugin.config.useNullish ? identifiers.nullish : identifiers.optional;
ast.expression = $(z).attr(method).call(ast.expression);
ast.typeName = plugin.config.useNullish
? identifiers.ZodMiniNullish
: identifiers.ZodMiniOptional;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid referencing non-existent z.ZodMiniNullish type

With useNullish enabled for the mini generator, this sets the type annotation to z.ZodMiniNullish, but Zod Mini doesn’t export a ZodMiniNullish type. That means the emitted TypeScript will reference an undefined type whenever optional properties are generated with .nullish(), breaking type checking in the mini output. It’s safer to keep the existing ZodMiniOptional type name (or skip the type annotation).

Useful? React with 👍 / 👎.

@codecov
Copy link

codecov bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 28.57143% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 34.91%. Comparing base (ce5977e) to head (4694719).

Files with missing lines Patch % Lines
packages/openapi-ts/src/plugins/zod/mini/plugin.ts 0.00% 5 Missing ⚠️
packages/openapi-ts/src/plugins/zod/v4/plugin.ts 0.00% 3 Missing ⚠️
packages/openapi-ts/src/plugins/zod/v3/plugin.ts 0.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3302   +/-   ##
=======================================
  Coverage   34.91%   34.91%           
=======================================
  Files         401      401           
  Lines       22237    22246    +9     
  Branches     1429     1429           
=======================================
+ Hits         7763     7767    +4     
- Misses      14470    14475    +5     
  Partials        4        4           
Flag Coverage Δ
unittests 34.91% <28.57%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 3, 2026

Open in StackBlitz

@hey-api/codegen-core

npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/codegen-core@3302

@hey-api/nuxt

npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/nuxt@3302

@hey-api/openapi-ts

npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/openapi-ts@3302

@hey-api/shared

npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/shared@3302

@hey-api/types

npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/types@3302

@hey-api/vite-plugin

npm i https://pkg.pr.new/hey-api/openapi-ts/@hey-api/vite-plugin@3302

commit: 4694719

@mrlubos
Copy link
Member

mrlubos commented Feb 3, 2026

@hbmartin Hey, appreciate the pull request, but if there's an issue with the spec, that should be fixed at the spec level. As such, this pull request isn't going to get merged. The linked issues are not related to the problem you're describing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 🚀 Feature request. size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants