Integrate Prettify to get rid of intersection types
TomasHubelbauer opened this issue · comments
Bug report
Hi, this is an improvement suggestion and I have first opened a documentation thread for this but it has not seen any activity since I opened it last week so I figure I'd reopen it here to give it a chance to get some attention.
Describe the bug
When using Postgrest .select('a,b,c')
we get an intersection type back: { a: type; } & { b: type } & { c: type }
.
To Reproduce
- Check out https://github.com/supabase/postgrest-js
- Add this code snippet to
index.test-d.ts
:{ const { data, error } = await postgrest .from('users') .select('username,data,status') if (error) { throw new Error(error.message) } expectType<{ username: string; data: Json; status: "ONLINE" | "OFFLINE" | null; }[]>(data) }
- Hover over
data
to see its real type - Observe the inferred type is an intersection type
Expected behavior
I am hoping we can incorporate this to make the type non-intersected:
type Prettify<T> = { [K in keyof T]: T[K] } & {};
Credit goes to https://twitter.com/mattpocockuk/status/1622730173446557697.
Screenshots
Currently we get this inferred type when hovering over data
from select
:
{
username: string;
} & {
data: Json;
} & {
status: "ONLINE" | "OFFLINE" | null;
}
With Prettify
hovering over the select
response data
we'll see this inferred type:
{
username: string;
data: Json;
status: "ONLINE" | "OFFLINE" | null;
}
Hey, this looks great! Would definitely want this in the lib :)
Amazingly, I managed to write all this text and yet forgot to include a link to the original discussion thread :D
supabase/supabase#12292
I already tried implementing this but ran into a problem. Citing myself from that thread:
I am hoping
Prettify
could be somehow integrated into thepostgrest-js
types so I looked atsrc/types.ts
. I clicked throughdata
anderror
toPostgrestResponseSuccess
andPostgrestResponseFailure
.
I cannot just extend
PostgrestResponseSuccess
like so because the response is potentially an array:>
+ type Prettify<T> = { [K in keyof T]: T[K] } & {};
export interface PostgrestResponseSuccess<T> extends PostgrestResponseBase {
error: null
- data: T
+ data: Prettify<T>
count: number | null
}
I tried extending
PostgrestSingleResponse<T>
instead:
type Prettify<T> = { [K in keyof T]: T[K] } & {};
export type PostgrestSingleResponse<T> =
- | PostgrestResponseSuccess<T>
+ | PostgrestResponseSuccess<Prettify<T>>
| PostgrestResponseFailure
This didn't work, the inferred type was still intersected. I also tried wrapping
T
inPostgrestMaybeSingleResponse
andPostgrestResponse
but the result was the same.
I see these response types are only exported from the package but not really used internally.
Where else should I look to integrate
Prettify
? I realize thatselect
is not the only endpoint returning possibly interesected types, DB functions will probably do it, too? How can I enumerate all of the possible placesPrettify
could be added to?
Can you help me out with where to put Prettify
?
I see, so I guess it only works on one layer.
Can you try this diff?
diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts
index dc90ec7..5f8c5a7 100644
--- a/src/select-query-parser.ts
+++ b/src/select-query-parser.ts
@@ -1,6 +1,6 @@
// Credits to @bnjmnt4n (https://www.npmjs.com/package/postgrest-query)
-import { GenericSchema } from './types'
+import { GenericSchema, Prettify } from './types'
type Whitespace = ' ' | '\n' | '\t'
@@ -342,7 +342,7 @@ type GetResultHelper<
? GetResultHelper<Schema, Row, [], ConstructFieldDefinition<Schema, Row, R> & Acc>
: Fields extends [infer R, ...infer Rest]
? GetResultHelper<Schema, Row, Rest, ConstructFieldDefinition<Schema, Row, R> & Acc>
- : Acc
+ : Prettify<Acc>
/**
* Constructs a type definition for an object based on a given PostgREST query.
diff --git a/src/types.ts b/src/types.ts
index f9bbf66..f2464d3 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -69,3 +69,5 @@ export type GenericSchema = {
Views: Record<string, GenericView>
Functions: Record<string, GenericFunction>
}
+
+export type Prettify<T> = { [K in keyof T]: T[K] } & {}
:tada: This issue has been resolved in version 1.4.1 :tada:
The release is available on:
Your semantic-release bot 📦🚀