drizzle-team / drizzle-team/drizzle-orm

[Enhancement]: Allow different input/output types on customType

Open
#1,621 3 comments 5 reactions 0 assignees View on GitHub
enhancement
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.29.1

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

_No response_

### Describe the Bug

In the following code, when you insert, you should be able to input both `Vector` and `number[]`

```ts
export const customVector = customType<{
data: Vector|number[];
driverData: string;
config: { dimensions: number };
}>({
dataType(config) {
if (!config) {
return `vector(1536)`;
}
return `vector(${config.dimensions})`;
},
toDriver(value: Vector | number[]): string {
return toSql(value);
},

fromDriver(value: string): Vector {
return fromSql(value);
},
});

function fromSql(value: string) {
return new Vector(
value
.substring(1, value.length - 1)
.split(",")
.map((v) => parseFloat(v))
);
}

function toSql(value: Vector | number[]) {
return JSON.stringify(value);
}
```

Both of these work:
```ts
await db.insert(schema.myTable).values({ id: "1", embedding: [1, 2, 3] });
await db.insert(schema.myTable).values({ id: "1", embedding: new Vector([1, 2, 3]) });
```

This is great, however, given the fromDriver ALWAYS returns a vector, it should be able to correctly infer that it's a `Vector` type.
However, when querying the database, it returns as `Vector | number[]`
```ts
const myEmbeddingQuery = await db.select({ embedding: schema.myTable.embedding }).from(schema.myTable);
// ^? const myEmbeddingQuery: { embedding: Vector | number[];}[]
```

It seems to simply use the `data: Vector | number[];` type from the `customType`, however I've looked in the codebase and it should be able to infer the type based on the `fromDriver`.
https://github.com/drizzle-team/drizzle-orm/blob/0a4e3b265ce121675e7baa14f3a39669ea387e6d/drizzle-orm/src/pg-core/columns/custom.ts#L60-L83

### Expected behavior

Custom types should be able to have different input/output types.
Being able to transform data at the ORM-level would be such a powerful ability, in ensuring that data is always the format that you want it to be, without having to transform on every query.

### Environment & setup

_No response_

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.