Checking Joined Data Directly from Type Recommendation and Retrieved Data in Dynamic findMany

When implementing a join using with in findMany, I wrote the following code to dynamically change the object to be set in with.
// normal
const result = await dbToUse.query.user.findMany({
columns: { password: false },
...queryOptions,
with: {
Company: {
columns: companyJoinColumns,
with: { Users: true },
},
Partner: { columns: companyJoinColumns },
},
});
// normal
const result = await dbToUse.query.user.findMany({
columns: { password: false },
...queryOptions,
with: {
Company: {
columns: companyJoinColumns,
with: { Users: true },
},
Partner: { columns: companyJoinColumns },
},
});
my code I wrote this code because I wanted to allow users of the API to choose which objects to join.
// ex) offJoin = ["Company.User", "Partner"],
export const modifyWithOptions = (withOptions: any, offJoin: string[] | undefined, path: string = ''): any => {
if (!offJoin) {
return withOptions;
}
return Object.keys(withOptions).reduce((acc, key) => {
const currentPath = path ? `${path}.${key}` : key;
if (offJoin.includes(currentPath)) {
return acc;
}

const value = withOptions[key];
if (value.with) {
value.with = modifyWithOptions(value.with, offJoin, currentPath);
}

return { ...acc, [key]: value };
}, {});
};


const result = await dbToUse.query.user.findMany({
columns: { password: false },
...queryOptions,
with: modifyWithOptions(
{
Company: {
columns: companyJoinColumns,
with: { Users: true },
},
Partner: { columns: companyJoinColumns },
},
params.offJoin
),
});

//I want to use type inference in the modifyWithOptions function and have the data I include with in the results of findMany appear as recommendations.
// ex) offJoin = ["Company.User", "Partner"],
export const modifyWithOptions = (withOptions: any, offJoin: string[] | undefined, path: string = ''): any => {
if (!offJoin) {
return withOptions;
}
return Object.keys(withOptions).reduce((acc, key) => {
const currentPath = path ? `${path}.${key}` : key;
if (offJoin.includes(currentPath)) {
return acc;
}

const value = withOptions[key];
if (value.with) {
value.with = modifyWithOptions(value.with, offJoin, currentPath);
}

return { ...acc, [key]: value };
}, {});
};


const result = await dbToUse.query.user.findMany({
columns: { password: false },
...queryOptions,
with: modifyWithOptions(
{
Company: {
columns: companyJoinColumns,
with: { Users: true },
},
Partner: { columns: companyJoinColumns },
},
params.offJoin
),
});

//I want to use type inference in the modifyWithOptions function and have the data I include with in the results of findMany appear as recommendations.
Is there a way to check the joined data directly from the type recommendation and the retrieved data? Or is this approach itself wrong?
3 Replies
Angelelz
Angelelz12mo ago
This approach would work if you wrap the db call in a generic function Check out this example https://discord.com/channels/1043890932593987624/1176396088895356959/1176537371764867155
sizzF
sizzFOP12mo ago
Thanks so much Angelelz, I'll check that out quickly. Thanks, I can define the with type in advance. However, since the items in the with are determined dynamically, I have no way of knowing what types are in the result. I'm happy with this though. schema.ts
export type FindManyUserWithOptions = NonNullable<Parameters<typeof db['query']['user']['findMany']>[0]>['with']
export type FindFirstUserWithOptions = NonNullable<Parameters<typeof db['query']['user']['findFirst']>[0]>['with']
export type FindManyUserWithOptions = NonNullable<Parameters<typeof db['query']['user']['findMany']>[0]>['with']
export type FindFirstUserWithOptions = NonNullable<Parameters<typeof db['query']['user']['findFirst']>[0]>['with']
handler.ts
const result = await dbToUse.query.user.findMany({
columns: { password: false },
...queryOptions,
with: modifyWithOptions(
{
Company: {
columns: companyJoinColumns,
with: { Users: true },
},
Partner: { columns: companyJoinColumns },
} as FindManyUserWithOptions,
params.offJoin
)
});
const result = await dbToUse.query.user.findMany({
columns: { password: false },
...queryOptions,
with: modifyWithOptions(
{
Company: {
columns: companyJoinColumns,
with: { Users: true },
},
Partner: { columns: companyJoinColumns },
} as FindManyUserWithOptions,
params.offJoin
)
});
Angelelz
Angelelz12mo ago
Yes, there is. In the typescript playground, the function getEmployeeById accepts a withInput argument, which is dynamic. You can check that if you change it, the resulting type will change I you add photos: true, you can see how the type of user changes
Want results from more Discord servers?
Add your server