Is there a way I can use relational types?

I'm currently trying to make a helper function that essentially wraps a database call, but I can't seem to find nor hack myself into getting a type for the with parameter in the relational queries. I've tried things like
type T = NonNullable<Parameters<typeof db.query.projects.findFirst>[0]>["with"];
type T = NonNullable<Parameters<typeof db.query.projects.findFirst>[0]>["with"];
but even that didnt work. any pointers?
9 Replies
bereket
bereket17mo ago
+1 @Andrew Sherman any idea for a fix? sorry for the ping btw, this issue has just been frusturating
Andrii Sherman
Andrii Sherman17mo ago
I need to call @Dan Kochetov here
bereket
bereket17mo ago
Hey! @Dan Kochetov - hopeful that you might have an idea to this 🙏
Dan
Dan17mo ago
Since the with parameter is recursive (there might be nested relations), its shape depends on several parameters: 1. Your schema 2. Which table does it belong to So your type should be generic and might look like this:
type ExtractWith<TFullSchema extends Record<string, unknown>, TTableName extends keyof TSchema, TSchema extends ExtractTablesWithRelations<TSchema> = ExtractTablesWithRelations<TSchema>> = DBQueryConfig<'one' | 'many', boolean, TSchema, TSchema[TTableName]>['with'];
type ExtractWith<TFullSchema extends Record<string, unknown>, TTableName extends keyof TSchema, TSchema extends ExtractTablesWithRelations<TSchema> = ExtractTablesWithRelations<TSchema>> = DBQueryConfig<'one' | 'many', boolean, TSchema, TSchema[TTableName]>['with'];
And could be used like this, based on the your code:
import * as schema from './schema';
type T = ExtractWith<typeof schema, 'projects'>;
import * as schema from './schema';
type T = ExtractWith<typeof schema, 'projects'>;
Keep in mind that projects in this case is your table variable name in TypeScript (i.e. export const projects = ...), not the table name in the DB. It might also be more useful for you to utilize the DB instance for the type instead of re-imporing the schema. If that's the case, let me know and I'll change the type to use it. I'll just post the second option right away
type ExtractWith<TDB extends PgDatabase, TTableName extends keyof TSchema> = DBQueryConfig<'one' | 'many', boolean, TDB['_']['schema'], TDB['_']['schema'][TTableName]>['with'];

type T = ExtractWith<typeof db, 'projects'>;
type ExtractWith<TDB extends PgDatabase, TTableName extends keyof TSchema> = DBQueryConfig<'one' | 'many', boolean, TDB['_']['schema'], TDB['_']['schema'][TTableName]>['with'];

type T = ExtractWith<typeof db, 'projects'>;
cody
codyOP17mo ago
Works great! thank you dan!
bereket
bereket17mo ago
Thanks so much for this ❤️ Much love
cody
codyOP17mo ago
Sorry for the double question, but is there also a way to infer return types from findFirst with ExtractWith? Trying to make this function use a generic to return the correct data too as the implicit return data is technically false (bc typescript doesnt know)
bereket
bereket16mo ago
👍 awesome, thanks @cod.e were you able to fix this? looks like im running into some issues thx! ;D
Want results from more Discord servers?
Add your server