Skip to content

fix(orm, zod): allow null in inferred type of required Json fields (#2647)#2649

Merged
ymc9 merged 1 commit intodevfrom
fix/json-null-inference-2647
May 6, 2026
Merged

fix(orm, zod): allow null in inferred type of required Json fields (#2647)#2649
ymc9 merged 1 commit intodevfrom
fix/json-null-inference-2647

Conversation

@ymc9
Copy link
Copy Markdown
Member

@ymc9 ymc9 commented May 6, 2026

Summary

  • A required Json column can hold a JSON null, but the inferred model type didn't include null — Prisma's JsonValue does. Widen TypeMap.Json in @zenstackhq/orm and JsonValue in @zenstackhq/zod so reads expose null correctly.
  • Filter and mutation types are unaffected: they reference JsonValue from @zenstackhq/orm directly (which stays narrow), so explicit JsonNull / DbNull markers continue to be required there.
  • The runtime zod schema in @zenstackhq/zod already accepted null; this just aligns the inferred type with runtime behavior.

Fixes #2647.

Test plan

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • JSON fields now support null values in type definitions and runtime parsing.
  • Tests

    • Added regression tests to validate null handling for JSON fields across type inference and runtime parsing scenarios.

…2647)

A required Json column can hold a JSON `null`, so the inferred model
type must include `null`. Widen `TypeMap.Json` in @zenstackhq/orm and
`JsonValue` in @zenstackhq/zod to align with Prisma's read semantics
(the runtime zod schema already accepted null).

Filter and mutation types are unaffected — they reference `JsonValue`
from @zenstackhq/orm directly, which stays narrow, so explicit
`JsonNull`/`DbNull` markers continue to be required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 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: 93a87283-51e0-4989-b9b5-059defff027d

📥 Commits

Reviewing files that changed from the base of the PR and between 090be2c and 2560233.

📒 Files selected for processing (5)
  • packages/orm/src/utils/type-utils.ts
  • packages/zod/src/types.ts
  • tests/regression/test/issue-2647/regression.test.ts
  • tests/regression/test/issue-2647/schema.ts
  • tests/regression/test/issue-2647/schema.zmodel

📝 Walkthrough

Walkthrough

This PR updates JSON value type definitions to permit null at the top level for required Json fields, fixing a type–runtime mismatch where Zod accepted null but TypeScript types did not. Regression test case is added for issue #2647.

Changes

JSON Type Nullability Alignment

Layer / File(s) Summary
Type Definition Updates
packages/zod/src/types.ts, packages/orm/src/utils/type-utils.ts
JsonValue is updated to include null in the union; JsonObject and JsonArray remove explicit null and reference JsonValue instead, allowing nullability to propagate consistently.
Regression Test Schema
tests/regression/test/issue-2647/schema.zmodel, tests/regression/test/issue-2647/schema.ts
New schema definition with PostgreSQL datasource and a Test model containing a metaData Json field; TypeScript schema class is generated with model metadata.
Regression Test
tests/regression/test/issue-2647/regression.test.ts
Three tests validate that null is assignable to the required metaData Json field in ORM-inferred types, Zod-inferred types, and runtime parsing via safeParse().

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A null once wandered, lost and feared,
Through Json fields where none appeared,
Now TypeScript agrees with Zod's release—
Top-level null finds blessed peace!
No silent types, the schema's sound.

🚥 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 accurately captures the main change: allowing null in the inferred type for required Json fields across both @zenstackhq/orm and @zenstackhq/zod packages.
Linked Issues check ✅ Passed The PR successfully addresses all coding objectives from issue #2647: JsonValue types are updated to include null in both packages, filter/mutation types remain unchanged, runtime Zod schema behavior is preserved, and comprehensive regression tests validate the changes.
Out of Scope Changes check ✅ Passed All changes are directly scoped to resolving the null type mismatch: type updates in orm/zod packages, runtime test infrastructure, and regression tests for validation. No extraneous modifications.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/json-null-inference-2647

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.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 6, 2026

Claude finished @ymc9's task —— View job


PR Review: JSON Null Inference Fix

Reviewing the changes to fix null inference in required Json fields...

Todo List

  • Analyze type changes in packages/orm/src/utils/type-utils.ts
  • Review zod type modifications in packages/zod/src/types.ts
  • Examine regression test implementation
  • Assess code quality and potential issues
  • Evaluate test coverage
  • Provide comprehensive review feedback

Review Summary

This PR successfully addresses issue #2647 by properly aligning the TypeScript type inference for required Json fields with their actual runtime behavior. The changes are minimal, focused, and well-tested.

✅ Code Quality & Best Practices

Excellent implementation - The changes follow the existing codebase patterns perfectly:

  1. Minimal, surgical changes: Only two lines modified in core type definitions:

    • packages/orm/src/utils/type-utils.ts:43: Json: JsonValue | null
    • packages/zod/src/types.ts:138: JsonValue = string | number | boolean | JsonObject | JsonArray | null
  2. Consistent with existing patterns: The fix aligns with how Prisma's JsonValue type already includes null, maintaining compatibility

  3. Clean separation of concerns: Filter and mutation types remain narrow (requiring explicit JsonNull/DbNull markers) while read types are correctly widened

🔍 Type Safety Analysis

Strong type safety maintained:

  • Read operations correctly expose null as a possible value (matches database reality)
  • Write operations still require explicit null markers (JsonNull/DbNull) for clarity
  • The NonNullable<> utility cleanly strips the new null from existing code that doesn't expect it

🧪 Test Coverage

Comprehensive test coverage with the new regression test:

// Tests all three critical aspects:
expectTypeOf<null>().toExtend<Test['metaData']>(); // ORM type inference
expectTypeOf<null>().toExtend<Test['metaData']>(); // Zod type inference  
expect(_schema.safeParse({ metaData: null }).success).toBe(true); // Runtime behavior

The test correctly validates that:

  1. ORM-inferred types allow null
  2. Zod-inferred types allow null
  3. Runtime parsing accepts null values

🔐 Security Considerations

No security concerns identified:

  • Changes are purely type-level improvements
  • No new attack vectors introduced
  • Maintains existing null-handling patterns

⚡ Performance Considerations

Zero performance impact:

  • Changes are compile-time only
  • No runtime overhead added
  • Existing validation logic unchanged

🎯 Backward Compatibility

Excellent backward compatibility:

  • Existing code using NonNullable<> continues working unchanged
  • Filter/mutation APIs unchanged (still require explicit null markers)
  • Only widens types where appropriate (read operations)

🔗 Integration Points

Well-integrated with existing systems:


Recommendation: ✅ APPROVE

This is a high-quality fix that:

  • Solves the reported issue precisely
  • Maintains excellent type safety
  • Includes comprehensive test coverage
  • Has zero breaking changes
  • Follows established patterns

The implementation demonstrates strong understanding of TypeScript's type system and careful consideration of the broader codebase architecture.

@ymc9 ymc9 merged commit d5e7900 into dev May 6, 2026
8 checks passed
@ymc9 ymc9 deleted the fix/json-null-inference-2647 branch May 6, 2026 02:14
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.

fix(zod): top-level null mismatch in makeJsonSchema() for required Json fields

1 participant