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.54k stars 643 forks source link

[Enhancement]: Generated type #2685

Closed incompletude closed 2 months ago

incompletude commented 3 months ago

What version of drizzle-orm are you using?

LTS

What version of drizzle-kit are you using?

LTS

Describe the Bug

This is more like an enhancement, and I'm not sure is even possible, but it would be nice if the InferSelectModel preserved the column order as defined in the table:

export const CompanyTable = pgTable("company", {
  id: text("company_id")
    .primaryKey()
    .$default(() => typeid("company").toString()),
  name: text("name").notNull(),
  createdAt: timestamp("created_at", { withTimezone: true })
    .notNull()
    .$default(() => new Date()),
  updatedAt: timestamp("updated_at", { withTimezone: true })
    .notNull()
    .$onUpdate(() => new Date()),
})

export type Company = InferSelectModel<typeof CompanyTable>

Resulting type is:

type Company = {
    name: string;
    id: string;
    createdAt: Date;
    updatedAt: Date;
}

Should be:

type Company = {
    id: string;
    name: string;
    createdAt: Date;
    updatedAt: Date;
}

When working with complex types having the ordering as is helps organize stuff around.

Expected behavior

No response

Environment & setup

No response

incompletude commented 3 months ago

Not sure what is going on here, sometimes it works, sometimes it doesnt. I think is something related to vscode and ts.

L-Mario564 commented 2 months ago

Typescript's type system is structural so it alongside many developers are not concerned with preserving the order of the keys in an object. This would be a very hard thing to implement in Drizzle for very little reward, by that I mean that preserving the order of keys is a very niche use case to begin with. You could create a utility type if you really need it, something like:

type User = { name: string; id: number; };

type Reorder<T, K extends (keyof T)[]> = {
  [Key in K[number]]: T[Key];
};

type Ordered = Reorder<User, ['id', 'name']>; // { id: number; name: string; }

Not ideal, sure, but this is more of a limitation of Typescript's type system rather than Drizzle.