Skip to content

fix(zod): properly infer scalar array types#2500

Merged
ymc9 merged 7 commits intozenstackhq:devfrom
haltcase:fix/zod-scalar-array-types
Mar 20, 2026
Merged

fix(zod): properly infer scalar array types#2500
ymc9 merged 7 commits intozenstackhq:devfrom
haltcase:fix/zod-scalar-array-types

Conversation

@haltcase
Copy link
Contributor

@haltcase haltcase commented Mar 19, 2026

Closes #2499

I haven't added a test case yet because the current zmodel used for testing the zod package specifies sqlite which doesn't support array types.

Edit: I've now added a test case but it required switching the provider to postgresql and regenerating the schema. Let me know if that's not desired.

Summary by CodeRabbit

  • Refactor

    • Improved internal handling so scalar fields declared as arrays are recognized as arrays before optional/nullable processing.
  • Tests

    • Added/updated test coverage for array-typed scalar fields (e.g., Post.tags inferred as string[] for create/update).
    • Test schema switched to PostgreSQL and includes new array fields (Post.tags, Address.residents).

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2026

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: 2d2589e3-55f9-47db-a67a-5aafd22cc16d

📥 Commits

Reviewing files that changed from the base of the PR and between 03b35b9 and ceca136.

📒 Files selected for processing (4)
  • packages/zod/src/types.ts
  • packages/zod/test/factory.test.ts
  • packages/zod/test/schema/schema.ts
  • packages/zod/test/schema/schema.zmodel
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/zod/src/types.ts
  • packages/zod/test/schema/schema.zmodel

📝 Walkthrough

Walkthrough

Zod type composition updated so scalar fields that are arrays are conditionally wrapped as Zod arrays before optional/nullable handling. Tests and test schema updated to add tags: String[] on Post and residents: String[] on Address; test provider changed to postgresql.

Changes

Cohort / File(s) Summary
Type definitions
packages/zod/src/types.ts
Mapped scalar field Zod schemas are now conditionally wrapped with ZodArrayIf<..., FieldIsArray<...>> (and TypeDefFieldIsArray for typedefs) before applying ZodOptionalAndNullableIf / optional wrappers. Review: conditional array wrap and import additions.
Tests
packages/zod/test/factory.test.ts
Added tags array to validPost fixture and extended schema type assertions to expect string[] for model/create/update schemas; adjusted Address test inputs to include residents: [].
Test schema (TS)
packages/zod/test/schema/schema.ts
Changed SchemaType.provider.type from sqlitepostgresql; added Post.tags as { name: "tags", type: "String", array: true } and Address.residents similarly.
Test schema (zmodel)
packages/zod/test/schema/schema.zmodel
Datasource provider switched to postgresql; added residents String[] to type Address and tags String[] to model Post; minor formatting/spacing adjustments in models.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇
I nuzzled types that lost their hop,
Wrapped lone strings so arrays don't stop,
Planted tags and residents in rows,
Tests now sing where inference grows,
🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(zod): properly infer scalar array types' directly addresses the main change: correcting TypeScript type inference for scalar array types in the Zod package.
Linked Issues check ✅ Passed Changes in types.ts apply ZodArrayIf conditionally for scalar arrays [#2499], test schema updated to support arrays [#2499], and inferred types now match runtime behavior [#2499].
Out of Scope Changes check ✅ Passed All changes directly support fixing scalar array type inference: type logic fixes, test infrastructure updates (provider change, schema additions), and test case coverage for array types.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Tip

You can customize the high-level summary generated by CodeRabbit.

Configure the reviews.high_level_summary_instructions setting to provide custom instructions for generating the high-level summary.

Required to support list types

Regenerated schema with:

`pnpm --package=@zenstackhq/cli dlx zen generate --schema ./test/schema/schema.zmodel --output ./test/schema --generate-models=false --generate-input=false`
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/zod/src/types.ts (1)

53-76: ⚠️ Potential issue | 🟡 Minor

Both GetModelCreateFieldsShape and GetModelUpdateFieldsShape need the ZodArrayIf wrapper for consistent array type inference.

These types were missing the same fix applied to GetModelFieldsShape. While runtime validation works correctly (the factory's applyCardinality method properly wraps schemas with .array()), the TYPE definitions don't reflect this, causing incorrect TypeScript type inference for scalar array fields in create/update operations.

Apply the suggested fixes to ensure proper type inference across all shape types.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/zod/src/types.ts` around lines 53 - 76, Wrap the mapped field Zod
schema with ZodArrayIf in both GetModelCreateFieldsShape and
GetModelUpdateFieldsShape like you did in GetModelFieldsShape: replace
MapModelFieldToZod<Schema, Model, Field> with
ZodArrayIf<MapModelFieldToZod<Schema, Model, Field>, /* same array-condition
used in GetModelFieldsShape */> so the existing wrappers (ZodOptionalIf,
ZodOptionalAndNullableIf, z.ZodOptional) continue to apply to the array-aware
schema; update both GetModelCreateFieldsShape and GetModelUpdateFieldsShape
declarations accordingly, keeping the other conditional filters
(FieldIsRelation, FieldIsComputed, FieldIsDelegateDiscriminator) and utilities
(ModelFieldIsOptional, FieldHasDefault) intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/zod/src/types.ts`:
- Around line 53-76: Wrap the mapped field Zod schema with ZodArrayIf in both
GetModelCreateFieldsShape and GetModelUpdateFieldsShape like you did in
GetModelFieldsShape: replace MapModelFieldToZod<Schema, Model, Field> with
ZodArrayIf<MapModelFieldToZod<Schema, Model, Field>, /* same array-condition
used in GetModelFieldsShape */> so the existing wrappers (ZodOptionalIf,
ZodOptionalAndNullableIf, z.ZodOptional) continue to apply to the array-aware
schema; update both GetModelCreateFieldsShape and GetModelUpdateFieldsShape
declarations accordingly, keeping the other conditional filters
(FieldIsRelation, FieldIsComputed, FieldIsDelegateDiscriminator) and utilities
(ModelFieldIsOptional, FieldHasDefault) intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b733e876-e054-4103-845d-a68d36aa91bc

📥 Commits

Reviewing files that changed from the base of the PR and between 00768de and 7d1429c.

📒 Files selected for processing (1)
  • packages/zod/src/types.ts

Copy link
Member

@ymc9 ymc9 left a comment

Choose a reason for hiding this comment

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

Thanks for the fix @haltcase ! LGTM. Left one comment there.

@haltcase
Copy link
Contributor Author

Thanks for the fix @haltcase ! LGTM. Left one comment there.

@ymc9 updated!

@ymc9
Copy link
Member

ymc9 commented Mar 20, 2026

Thanks for the fix @haltcase ! LGTM. Left one comment there.

@ymc9 updated!

Thanks! Will merge when CI passes. It'll be included in v3.5.

@ymc9 ymc9 merged commit 41ea0c9 into zenstackhq:dev Mar 20, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@zenstackhq/zod scalar array types are incorrect

2 participants