Skip to content

fix(typescript): generate non-nullable json columns as NonNullable<Json>#1085

Open
Maliik-B wants to merge 1 commit into
supabase:masterfrom
Maliik-B:fix/jsonb-not-null-nullability
Open

fix(typescript): generate non-nullable json columns as NonNullable<Json>#1085
Maliik-B wants to merge 1 commit into
supabase:masterfrom
Maliik-B:fix/jsonb-not-null-nullability

Conversation

@Maliik-B

Copy link
Copy Markdown

Problem

A NOT NULL json/jsonb column generates the TypeScript type Json, but the generated Json type is itself nullable:

export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[]

So the column type structurally permits null even though Postgres forbids it. Studio reports the column as non-nullable, but the generated types disagree.

Closes #1055.

Fix

generateNullableUnionTsType already special-cases unknown/any (which include null) by not appending | null. This applies the same reasoning to Json: a non-nullable json/jsonb column is narrowed to NonNullable<Json> so the type reflects the database constraint.

if (tsType === 'Json' && !isNullable) {
  return `NonNullable<${tsType}>`
}

Scope

  • Only non-nullable json/jsonb columns change (Json becomes NonNullable<Json>). Nullable json columns are untouched, since Json already covers null.
  • The change sits in the single nullability chokepoint, so it covers Row, Insert, and Update consistently. Function return types and composite-type attributes call this helper with isNullable: true, so they are unaffected. Array types ((Json)[]) are unaffected.

Tests

Added a regression test that spins up a throwaway schema with a NOT NULL jsonb column and a nullable jsonb column, generates types scoped to it, and asserts the non-nullable column is NonNullable<Json> while the nullable one stays Json | null. It follows the inline-schema pattern from the existing included/excluded-schemas test, so it adds no fixture churn to the shared snapshots.

Note on the type-generation extraction

I see #1084 and supabase/pg-toolbelt#302 are moving these templates into @supabase/postgrest-typegen. This patch targets typescript.ts here; happy to port the same one-line guard to the extracted package instead if that is the better home. @avallete

The generated Json type includes null, so a NOT NULL json/jsonb column was typed as nullable. Narrow it to NonNullable<Json> in the nullability helper so the type reflects the database constraint. Nullable json columns are unchanged since Json already covers null.

Closes supabase#1055
@Maliik-B Maliik-B requested review from a team, avallete and soedirgo as code owners June 20, 2026 19:59
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.

Generated type for JSONB NOT NULL column allows null

1 participant