K
Kysely11mo ago
Nikola

Dynamic return type based on provided select array

So I have this function:
async getBillableUsers(select: SelectExpression<DB, 'user_data'>[]) {
return this.db
.selectFrom('user_data')
.select(select)
.where((eb) => eb.or([eb('billability_type', '=', 'Billable'), eb('billability_type', 'is', null)]))
.execute();
}
async getBillableUsers(select: SelectExpression<DB, 'user_data'>[]) {
return this.db
.selectFrom('user_data')
.select(select)
.where((eb) => eb.or([eb('billability_type', '=', 'Billable'), eb('billability_type', 'is', null)]))
.execute();
}
And when I call it I want the return type to contain only the fields that were provided in the select parameter.
const billableUsers = await this.getBillableUsers(['id', 'work_email']);
const billableUsers = await this.getBillableUsers(['id', 'work_email']);
In the result above, billableUsers contains all user_data column values, how can I narrow it down? I tried a lot of things but I keep getting type errors. I am using the kysely-codegen library for the types. Thanks for the help!
Solution:
Took 2 hours but I think I figured it out. Here's my solution for anyone else who might stumble upon this problem. Feel free to leave better/smarter/faster/shorter alternatives. ```...
Jump to solution
1 Reply
Solution
Nikola
Nikola11mo ago
Took 2 hours but I think I figured it out. Here's my solution for anyone else who might stumble upon this problem. Feel free to leave better/smarter/faster/shorter alternatives.
async getBillableUsers<T extends SelectExpression<DB, 'user_data'>>(select: T[]) {
return this.db
.selectFrom('user_data')
.select(select)
.where((eb) => eb.or([eb('billability_type', '=', 'Billable'), eb('billability_type', 'is', null)]))
.execute();
}
async getBillableUsers<T extends SelectExpression<DB, 'user_data'>>(select: T[]) {
return this.db
.selectFrom('user_data')
.select(select)
.where((eb) => eb.or([eb('billability_type', '=', 'Billable'), eb('billability_type', 'is', null)]))
.execute();
}
Now:
const billableUsers = await this.getBillableUsers(['id', 'work_email']);
const billableUsers = await this.getBillableUsers(['id', 'work_email']);
correctly resolves to: const billableUsers: {id: string, work_email: string}[]
Want results from more Discord servers?
Add your server