drizzle-team / drizzle-team/drizzle-orm

[BUG]: typings are lost when using customType with known dataType

Open
#1,997 0 comments 3 reactions 0 assignees View on GitHub
bug db/postgres qb/crud
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.30.1

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

_No response_

### Describe the Bug

Hello.

We're using the `customType` to do simple overloads of the `toDriver`/`fromDriver` methods on well known data types (e.g. uuid) using postgresql. E.g.:

```ts
const customUuid = () =>
customType<{data: string; driverData: string}>({
dataType() {
return 'uuid';
},

fromDriver(value: string): string {
return addPrefix(value);
},

toDriver(value: string): string {
return removePrefix(value);
},
});
```

Doing this, we've discovered that even though the type being returned in the `dataType` function is a type well known to drizzle, the typing is lost when the query is built, eventually leading to our queries failing, since we're using the `AWS Data API` that receives no `typeHint` because of the missing typing [here](https://github.com/drizzle-team/drizzle-orm/blob/bfc757f2adb843192e1b5508fcb4abd9737edd09/drizzle-orm/src/aws-data-api/common/index.ts#L29-L45).

Looking at the codebase, this seems to come down to the fact that the typings are infered from the instance of the class (or alternatively from the `entityKind` field in the class) in

https://github.com/drizzle-team/drizzle-orm/blob/bfc757f2adb843192e1b5508fcb4abd9737edd09/drizzle-orm/src/pg-core/dialect.ts#L494-L512

which will always return `none` for custom types, since the class is `PgCustomColumn`.

I'm not familiar enough with the codebase to tell whether the following solution would introduce other issues, but I did some brief testing modifying the `prepareTyping` function to something like:

```ts
prepareTyping(encoder: DriverValueEncoder): QueryTypingsValue {
if (
is(encoder, PgJsonb) || is(encoder, PgJson) || (is(encoder, PgCustomColumn) && (encoder.getSQLType() === 'json' || encoder.getSQLType() === 'jsonb'))
) {
return 'json';
} else if (is(encoder, PgNumeric) || (is(encoder, PgCustomColumn) && encoder.getSQLType() === 'decimal')) {
return 'decimal';
} else if (is(encoder, PgTime) || (is(encoder, PgCustomColumn) && encoder.getSQLType() === 'time')) {
return 'time';
} else if (is(encoder, PgTimestamp) || (is(encoder, PgCustomColumn) && encoder.getSQLType() === 'timestamp')) {
return 'timestamp';
} else if (is(encoder, PgDate) || (is(encoder, PgCustomColumn) && encoder.getSQLType() === 'date')) {
return 'date';
} else if (is(encoder, PgUUID) || (is(encoder, PgCustomColumn) && encoder.getSQLType() === 'uuid')) {
return 'uuid';
} else {
return 'none';
}
}
```

to maintain the typing if it's well known. This worked successfully.

I was hoping that someone more familiar with the codebase could look into whether a solution like this would be feasible going forward?

### Expected behavior

Typings to be preserved when using known data types in `customType`.

### Environment & setup

Postgresql.

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.