postgrest-js
postgrest-js copied to clipboard
Wrong type for joins with one-to-one relationships
Bug report
- [x] I confirm this is a bug with Supabase, not with my own application.
- [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
I have a profiles
and a customers
table, with a one-to-one relationship:
profiles: {
id: text, primary key
...
}
customers: {
id: references profiles.id, primary key
stripe_customer_id: text, unique
...
}
When doing a join between these, TypeScript thinks the type of customers
is this:
{
stripe_customer_id: string;
}[]
But when I run the code, this is the actual type I get:
{
stripe_customer_id: string;
}
So when accessing the stripe_customer_id
property, I get this type error:
Property 'stripe_customer_id' does not exist on type '{ stripe_customer_id: string; }[]'.
To Reproduce
const profile_result = await supabase
.from('profiles')
.select('id, customers ( stripe_customer_id )')
.eq('id', params.id)
.single()
if (profile_result.data) {
console.log(profile_result.data.customers.stripe_customer_id)
// ^
// Property 'stripe_customer_id' does not exist on
// type '{ stripe_customer_id: string; }[]'.ts(2339)
}
Expected behavior
The TypeScript type should not be an array for one-to-one relationships. It should match the actual type
System information
- OS: macOS
- Version of supabase-js: 2.31.0
- Version of Node.js: 18.14.2
Additional context
Related:
- https://github.com/supabase/supabase-js/issues/723
I'm using this as a workaround for now:
export function cast<T>(notAnArray: T[]): T {
return notAnArray as T;
}
And then:
console.log(cast(profile_result.data.customers).stripe_customer_id)
Update: I've changed my workaround to this:
export function fixOneToOne<T>(objectOrNull: T[]): T | null {
return (objectOrNull as T) || null;
}
I've changed the return type to T | null
because the relationship may indeed be null
. In the example above, this would happen when there is no customers
record for the given profile.
In the example above, the correct type should be:
{
stripe_customer_id: string;
} | null
I encountered the same issue today and I found another workaround.
const profile_result = await supabase
.from('profiles')
.select('id, customers ( stripe_customer_id )')
.eq('id', params.id)
.single()
.returns<YourType[]>();
# type definition
type YourType {
the type that you expect without the array
}
I am experiencing the exact same issue. As my query is rather nested, workarounds are very inconvenient...
Does anyone know, whether an older version does not have this bug included?
Seems to still be an issue
Same problem over here, is there a fix for this issue??
Same problem here.
Yep, same here! Please fix when possible
Still a problem, please fix!
same problem for me