drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.02k stars 606 forks source link

[BUG]: Incorrect type when using a condition in relational query #824

Open MendyLanda opened 1 year ago

MendyLanda commented 1 year ago

What version of drizzle-orm are you using?

0.27.0

What version of drizzle-kit are you using?

0.19.1

Describe the Bug

The type from this query: image should be:

image

But instead, it's this:

image

Expected behavior

No response

Environment & setup

No response

MendyLanda commented 1 year ago

This is better, but the desired type here is a possible undefined.

image

I'm not sure if this is a bug or a fr, I searched the docs for this, but found none.

dankochetov commented 1 year ago

It's a type bug, will fix.

MendyLanda commented 1 year ago

While we wait for the official fix, I've come up with a temporary workaround for the issue. This should be useful if you're encountering the same problem.

First, copy & store this type somewhere:

/**
 * @param T The type of the result of the query.
 * @param Table The drizzle schema of the table that is being joined
 * @param K The key of the relation in the results
 */
export type FixQCondition<
  T extends Array<T[number]>,
  Table extends AnyTable, 
  K extends keyof T[number],
  Bad = Table["_"]["model"]["select"],
  Data = (T[number][K] extends Array<unknown> ? T[number][K][number] : never)
  > = {
  [TK in keyof T[number]]: TK extends K 
    ? (Data extends Bad ? never : Data)[] | undefined
    : T[number][TK];
}[];

Then you can use it like this:

const result = db.query.room.findMany({"Your conditional query" });
type Corrected = FixQCondition<typeof result, typeof children, "children">;
return result as Corrected;

For findFirst:

const result = db.query.room.findFirst({"Your conditional query" });
type Corrected = FixQCondition<typeof result[], typeof children, "children">[number]
return result as Corrected;

Caveat: If you have multiple conditional joins, it will get even more messy:

type FixChildren = FixQCondition<typeof result, typeof children, "children">;
type FixUpdates = FixQCondition<FixChildren, typeof updates, "updates">;
type FixTasks = FixQCondition<FixUpdates, typeof tasks, "tasks">;
MendyLanda commented 1 year ago

Issue still exists on v0.28.2, temporary fix still works.

arahiko-ayami commented 9 months ago

I think this bug should be fixed ASAP, it affects a popular use case of an ORM. And it is still here after more than half of year!