Is there really no way to construct a valid orderBy statement dynamically without $.dynamicQuery?

I realize I can append multiple orderBy statements with .$dynamic() But I'm wondering why a more direct approach doesn't work?
//Let's define a schema first
export const sortSchema = z.array(
z.object({
columnId: createSelectSchema(myTable).keyof(),
desc: z.boolean(),
})
);

//parse an object against that schema
const parsedSortSchema = sortSchema.safeParse(sortObject);
const sortToUse = parsedSortSchema.success
? parsedSortSchema.data
: undefined;

//create orderBy
const orderBy = sortToUse?.map((s) => {
return s.desc ? desc(myTable[s.columnId]) : asc(myTable[s.columnId]);
});

//so far so good (?), `orderBy` is of type `SQL<unknown>[] | undefined`.

//now, here comes the issue:
const { data, count } = await db.transaction(async (tx) => {
const data = await tx
.select()
.from(myTable)
.orderBy(orderBy ? {...orderBy} : desc(myTable.createdAt)); //T

const count = await tx
.select({
count: sql<number>`count(${myTable.id})`.mapWith(Number),
})
.from(myTable)
.execute()
.then((res) => res[0]?.count ?? 0);

return {
data,
count,
};
});
//Let's define a schema first
export const sortSchema = z.array(
z.object({
columnId: createSelectSchema(myTable).keyof(),
desc: z.boolean(),
})
);

//parse an object against that schema
const parsedSortSchema = sortSchema.safeParse(sortObject);
const sortToUse = parsedSortSchema.success
? parsedSortSchema.data
: undefined;

//create orderBy
const orderBy = sortToUse?.map((s) => {
return s.desc ? desc(myTable[s.columnId]) : asc(myTable[s.columnId]);
});

//so far so good (?), `orderBy` is of type `SQL<unknown>[] | undefined`.

//now, here comes the issue:
const { data, count } = await db.transaction(async (tx) => {
const data = await tx
.select()
.from(myTable)
.orderBy(orderBy ? {...orderBy} : desc(myTable.createdAt)); //T

const count = await tx
.select({
count: sql<number>`count(${myTable.id})`.mapWith(Number),
})
.from(myTable)
.execute()
.then((res) => res[0]?.count ?? 0);

return {
data,
count,
};
});
Error message is
1 Reply
samson
samson7mo ago
No overload matches this call.
Overload 1 of 2, '(builder: (aliases: { id: PgColumn<{ name: "id"; tableName: "myTable"; dataType: "string"; columnType: "PgVarchar"; data: string; driverParam: string; notNull: true; hasDefault: true; enumValues: [string, ...string[]]; baseColumn: never; }, {}, {}>; ... 6 more ...; otherTableId: PgColumn<...>; }) => ValueOrArray<...>): Omit<...>', gave the following error.
Argument of type 'SQL<unknown> | { [n: number]: SQL<unknown>; length: number; toString(): string; ... 34 more ...; [Symbol....' is not assignable to parameter of type '(aliases: { id: PgColumn<{ name: "id"; tableName: "myTable";... 6 more ...; otherTableId: PgColumn<...>; }) => ValueOrArray<...>'.
Type 'SQL<unknown>' is not assignable to type '(aliases: { id: PgColumn<{ name: "id"; ... 6 more ...; otherTableId: PgColumn<...>; }) => ValueOrArray<...>'.
Type 'SQL<unknown>' provides no match for the signature '(aliases: { id: PgColumn<{ name: "id"; tableName: "myTable"; dataType: "string"; ...6 more ...; otherTableId: PgColumn<...>; }): ValueOrArray<...>'.
Overload 2 of 2, '(...columns: (SQL<unknown> | PgColumn<ColumnBaseConfig<ColumnDataType, string>, {}, {}> | Aliased<unknown>)[]): Omit<PgSelectBase<"myTable", ... 6 more ..., { ...; }>, "limit" | ... 2 more ... | "offset">', gave the following error.
Argument of type 'SQL<unknown> | { [n: number]: SQL<unknown>; length: number; toString(): 34 more ...; [Symbol....' is not assignable to parameter of type 'SQL<unknown> | PgColumn<ColumnBaseConfig<ColumnDataType, string>, {}, {}> | Aliased<unknown>'.
Type '{ [n: number]: SQL<unknown>; length: number; toString(): string; toLocaleString(): string; pop(): ... 34 more ...; [Symbol.unscop...' is not assignable to type 'SQL<unknown> | PgColumn<ColumnBaseConfig<ColumnDataType, string>, {}, {}> | Aliased<unknown>'.ts(2769)
const orderBy: SQL<unknown>[]
No overload matches this call.
Overload 1 of 2, '(builder: (aliases: { id: PgColumn<{ name: "id"; tableName: "myTable"; dataType: "string"; columnType: "PgVarchar"; data: string; driverParam: string; notNull: true; hasDefault: true; enumValues: [string, ...string[]]; baseColumn: never; }, {}, {}>; ... 6 more ...; otherTableId: PgColumn<...>; }) => ValueOrArray<...>): Omit<...>', gave the following error.
Argument of type 'SQL<unknown> | { [n: number]: SQL<unknown>; length: number; toString(): string; ... 34 more ...; [Symbol....' is not assignable to parameter of type '(aliases: { id: PgColumn<{ name: "id"; tableName: "myTable";... 6 more ...; otherTableId: PgColumn<...>; }) => ValueOrArray<...>'.
Type 'SQL<unknown>' is not assignable to type '(aliases: { id: PgColumn<{ name: "id"; ... 6 more ...; otherTableId: PgColumn<...>; }) => ValueOrArray<...>'.
Type 'SQL<unknown>' provides no match for the signature '(aliases: { id: PgColumn<{ name: "id"; tableName: "myTable"; dataType: "string"; ...6 more ...; otherTableId: PgColumn<...>; }): ValueOrArray<...>'.
Overload 2 of 2, '(...columns: (SQL<unknown> | PgColumn<ColumnBaseConfig<ColumnDataType, string>, {}, {}> | Aliased<unknown>)[]): Omit<PgSelectBase<"myTable", ... 6 more ..., { ...; }>, "limit" | ... 2 more ... | "offset">', gave the following error.
Argument of type 'SQL<unknown> | { [n: number]: SQL<unknown>; length: number; toString(): 34 more ...; [Symbol....' is not assignable to parameter of type 'SQL<unknown> | PgColumn<ColumnBaseConfig<ColumnDataType, string>, {}, {}> | Aliased<unknown>'.
Type '{ [n: number]: SQL<unknown>; length: number; toString(): string; toLocaleString(): string; pop(): ... 34 more ...; [Symbol.unscop...' is not assignable to type 'SQL<unknown> | PgColumn<ColumnBaseConfig<ColumnDataType, string>, {}, {}> | Aliased<unknown>'.ts(2769)
const orderBy: SQL<unknown>[]
Want results from more Discord servers?
Add your server