drizzle-team / drizzle-team/drizzle-orm

[BUG]: Obscure Typescript errors during dynamic relational query formation.

Open
#2,966 0 comments 2 reactions 0 assignees View on GitHub
bug docs docs/undocumented priority rqb
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

### What version of `drizzle-orm` are you using?

0.33.0

### What version of `drizzle-kit` are you using?

0.22.6

### Describe the Bug

Raising this as an issue rather than a feature request. I've been banging my head against the table trying to troubleshoot Drizzle not properly handing the `columns` and `extras` fields in a relational sub-query, only to discover that the objects supplied to a query must be readonly at compile time.

Following is the relevant code snippets. The snippet works as expected, but omitting the `as const` from the object returned from `getBrandRelationalSelection()` results in a highly ambiguous Typescript error, also provided.

**The Typescript error does not accurately reflect the underlying issue, and I'm hoping this report can save others from the issue.**

```
const results = await db.query.matches.findMany({
where: and(
eq(matches.bracket, bracket.id),
firstRound ? eq(matches.matchRound, 0) : undefined,
),
with: {
brand_0: getBrandRelationalSelection(),
brand_1: getBrandRelationalSelection()
},
orderBy: [asc(matches.matchIndex)],
});

export function getBrandRelationalSelection() {
const {images, ...theRest} = getBrandSelection();
return {
columns: {
id: true,
name: true,
description: true,
pathName: true,
owner: true,
created: true,
lastUpdated: true,
url: true,
},
extras: {
images: images,
},
};
} as const;
```

Removing the `as const` from the object declaration in `getBrandRelationalSelection()` results in the following Type error:

```
Type error: Type '{ id: string; startTime: Date | null; endTime: Date | null; bracket: string; brand_0_id: string | null; brand_1_id: string | null; parentMatch: string | null; matchRound: number; matchIndex: number; winner: number | null; brand_0: { ...; } | null; brand_1: { ...; } | null; }[]' is not assignable to type 'Match[]'.
Type '{ id: string; startTime: Date | null; endTime: Date | null; bracket: string; brand_0_id: string | null; brand_1_id: string | null; parentMatch: string | null; matchRound: number; matchIndex: number; winner: number | null; brand_0: { ...; } | null; brand_1: { ...; } | null; }' is not assignable to type 'Match'.
Type '{ id: string; startTime: Date | null; endTime: Date | null; bracket: string; brand_0_id: string | null; brand_1_id: string | null; parentMatch: string | null; matchRound: number; matchIndex: number; winner: number | null; brand_0: { ...; } | null; brand_1: { ...; } | null; }' is not assignable to type '{ brand_0?: Brand | null | undefined; brand_1?: Brand | null | undefined; }'.
Types of property 'brand_0' are incompatible.
Type '{ images: ImagesObject; } | null' is not assignable to type 'Brand | null | undefined'.
Type '{ images: ImagesObject; }' is not assignable to type 'Brand'.
Type '{ images: ImagesObject; }' is missing the following properties from type 'Omit<{ id: string; name: string; description: string | null; pathName: string; stdImage: Date | null; openGraphImage: Date | null; url: string | null; owner: string | null; created: Date; lastUpdated: Date; }, "stdImage" | "openGraphImage">': id, name, description, pathName, and 4 more.
```

The `columns` field corrected omits two fields from the Brand object `stdImage` and `openGraphImage`; however, the Typescript error reports that the 8 requested columns are missing from the returned object containing `images`. This is an incoherent Type error.

### Expected behavior

Type error of non-statically const object be better reported.

### Environment & setup

Drizzle-orm 0.33.0
Typescript 5.5.4

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.