Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
monholm opened this issue Mar 12, 2024 · 0 comments · May be fixed by #2177
Open

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

monholm opened this issue Mar 12, 2024 · 0 comments · May be fixed by #2177
Labels
bug Something isn't working

Comments

@monholm
Copy link

monholm commented Mar 12, 2024

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.:

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.

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

prepareTyping(encoder: DriverValueEncoder<unknown, unknown>): QueryTypingsValue {
if (
is(encoder, PgJsonb) || is(encoder, PgJson)
) {
return 'json';
} else if (is(encoder, PgNumeric)) {
return 'decimal';
} else if (is(encoder, PgTime)) {
return 'time';
} else if (is(encoder, PgTimestamp)) {
return 'timestamp';
} else if (is(encoder, PgDate)) {
return 'date';
} else if (is(encoder, PgUUID)) {
return 'uuid';
} else {
return 'none';
}
}

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:

prepareTyping(encoder: DriverValueEncoder<unknown, unknown>): 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.

@monholm monholm added the bug Something isn't working label Mar 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant