Skip to content

Typescript: safer nullability in functions, domain support #573

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ngasull
Copy link

@ngasull ngasull commented Apr 25, 2023

What kind of change does this PR introduce?

Fixes #842

What is the current behavior?

CREATE DOMAIN strict_text AS text NOT NULL;

CREATE FUNCTION some_function(arg strict_text)
RETURNS table (nulltext text, stricttext strict_text)
LANGUAGE SQL AS $$
   SELECT NULL::text, arg
$$;

Generated type with supabase gen types typescript --local

export interface Database {
  public: {
    Functions: {
      some_function: {
        Args: {
          arg: unknown
        }
        Returns: {
          nulltext: string
          stricttext: unknown
        }[]
      }
    }
  }
}

What is the new behavior?

Generated types should be:

export interface Database {
  public: {
    Functions: {
      some_function: {
        Args: {
          arg: string
        }
        Returns: {
          nulltext: string | null
          stricttext: string
        }[]
      }
    }
  }
}

Please review tests for more details on new expected behavior.

  • Stop accepting non-nullable types in generated function arguments and return types.
  • Add support for domains and take their nullability into account.
  • Centralize nullability and array logic in pgTypeToTsType.

Additional context

This is obviously a breaking change for most users using functions. It is however the safe way, exposing sound types.

Add support for domains and take their nullability into account.
Centralize logic in `pgTypeToTsType`.
@ngasull ngasull requested review from a team as code owners April 25, 2023 09:08
@jumski
Copy link

jumski commented Nov 21, 2024

Hey @ngasull Postgres domains have some troubles with NOT NULL constraint:

CREATE DOMAIN in Postgres cannot safely enforce a NOT NULL constraint because domains are type aliases and do not directly validate constraints at the table level. While the domain itself can define a NOT NULL constraint, the database schema still allows null values in columns of that domain type unless the column explicitly defines NOT NULL. This behavior creates inconsistency: a domain's NOT NULL constraint is ignored unless explicitly reinforced on each column, leading to potential silent failures in enforcing the constraint.

But there is definitely a problem with serializing domain types with "gen-types" - they default to undefined.

@ngasull
Copy link
Author

ngasull commented Apr 24, 2025

@jumski This PR only aims to improve function generated types, no impact on tables. So the changes are still relevant.

Domains add a layer of safety over types at PostgreSQL runtime. Primitive types are unsafe (nullable) and it makes sense generate them as nullable unless they are a domain defined as NOT NULL.

@Donnerstagnacht
Copy link

Hi @soedirgo , just a quick ping to see if you (or another maintainer) might have a chance to take a look at this PR when you have time. It touches on issues discussed in #841 and #842 and it is open since 2 years but still relevant.

@jumski
Copy link

jumski commented Apr 24, 2025

@ngasull thanks for clarification,
TIL that domains can enforce NOT NULL when used to type function arguments.

Everything looks fine!

@eugeneford
Copy link

It would be incredibly amazing if we could have this done. When could we have this available?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Typescript gen : invalid SQL Function types
4 participants