cli
cli copied to clipboard
Generated JSON typescript type is not performant (source of infinite recursion)
Describe the bug Currently generated JSON typescript type is as follows:
export type Json =
| string
| number
| boolean
| null
| { [key: string]: Json | undefined }
| Json[];
The second to last line in particular can cripple typescript if used with certain tooling that depends on that type. Resulting in the following error:
Type instantiation is excessively deep and possibly infinite.ts(2589)
column: string | number | boolean | Json[] | {
[x: string]: string | number | boolean | Json[] | ... | null | undefined;
} | null;
It feels like this generated type doesn't add much use to anyone anyways. I think the best solution would be to set any JSON column as unknown, which it technically is, and let developers decide on the exact type.
I manually set the JSON definition to the below, and my vscode (on an M2 pro macbook) became alive again 🥳:
export type Json = unknown;
Not sure there's an easy way to overwrite the JSON column type in the userland, is there? Typefest's MergeDeep only merges, but doesn't overwrite the types (which can make the problem even worse).
To Reproduce TBD
Expected behavior No chance for infinite recursions in generated types types.
Screenshots TBD
System information
Rerun the failing command with --create-ticket
flag.
- Ticket ID: [e.g. ab1ac733e31e4f928a4d7c8402543712]
- Version of OS: latest OSX
- Version of CLI: 1.148.6
- Version of typescript: 5.4.2
Additional context Not relevant
I found a (temporary) fix to actually replace JSON types with typefest's MergeDeep:
MergeDeep<DatabaseGenerated, PUT_YOUR_MERGE_SCHEMA, { arrayMergeMode: "replace" }>
The default arrayMergeMode is "spread", which doesn't replace the JSON column by default, because it can be an array based on the default definition (wouldn't be a problem if it was unknown), so the resulting type ends up in:
{
column_name: CustomType[] | (Json | CustomType)[];
}
Instead of
{
column_name: CustomType;
}
type-fest doesn't really have proper docs, so it took me a bit of time to understand how to change the behavior.
The issue is still valid though, because unless you manually replace all instances of JSON columns, you can still unknowingly get pretty bad performance issues with the types. I had this for months, and only accidentally discovered the root cause. Hence unknown
is a much saner default.
Related
- https://github.com/supabase/supabase-js/issues/808
Hello all. Thanks for opening (and for the suggestions)!
As the issue is open on the JS library, we would close this one to keep the discussion (and work) centralised.