documented types for the return of `drizzle()` and the return of `mysqlTable()`

my most pressing need is documented types: https://github.com/drizzle-team/drizzle-orm/issues/273 Specifically the 2 that are holding me up right now are how to pass a the mysql2 version of drizzle() (aka a db reference) and a model reference (the result of mysqlTable()) around through my app
GitHub
Missing Documentation: Types · Issue #273 · drizzle-team/drizzle-orm
I spent the past 6 weeks trying out over a dozen different ORMs in the typescript world. They all have their pros and cons, but Drizzle seems to be one of the best when it comes to type safety. How...
18 Replies
alexblokh
alexblokh2y ago
please let me know if that's sufficient
import { int, varchar } from "drizzle-orm/mysql-core/columns";
import { InferModel, mysqlTable } from "drizzle-orm/mysql-core/table";
import { drizzle, MySql2Database } from "drizzle-orm/mysql2";

import mysql from "mysql2/promise";

// create the connection
const poolConnection = mysql.createPool({
host: "localhost",
user: "root",
database: "test",
});

const db: MySql2Database = drizzle(poolConnection);

export const usersTable = mysqlTable("user", {
id: int("id").autoincrement().primaryKey(),
name: varchar("name", { length: 255 }),
email: varchar("email", { length: 100 }),
});

type User = InferModel<typeof usersTable, "select">;

const getUsers = (): Promise<User[]> => {
return db.select().from(usersTable);
};
import { int, varchar } from "drizzle-orm/mysql-core/columns";
import { InferModel, mysqlTable } from "drizzle-orm/mysql-core/table";
import { drizzle, MySql2Database } from "drizzle-orm/mysql2";

import mysql from "mysql2/promise";

// create the connection
const poolConnection = mysql.createPool({
host: "localhost",
user: "root",
database: "test",
});

const db: MySql2Database = drizzle(poolConnection);

export const usersTable = mysqlTable("user", {
id: int("id").autoincrement().primaryKey(),
name: varchar("name", { length: 255 }),
email: varchar("email", { length: 100 }),
});

type User = InferModel<typeof usersTable, "select">;

const getUsers = (): Promise<User[]> => {
return db.select().from(usersTable);
};
JT
JTOP2y ago
for db yes, but not for the table i want to pass usersTable around
alexblokh
alexblokh2y ago
you're supposed to import it everywhere
JT
JTOP2y ago
not sufficient for my needs, i need to be able to pass it
alexblokh
alexblokh2y ago
please let me see your usecase
JT
JTOP2y ago
i'm not sure why "because i want to" isn't enough but my use case is that i'm going to be creating a generic composable object that will provide a shared set of functions to many different tables so when i instantiate that composable i need to pass it a table, so that it can perform all of it's various operations on that table
JT
JTOP2y ago
yes...i'm happy to show you around my actual project if you want to get that deep, but the gist is that i build a schema, part of building that schema is generating tables, and then ultimately that schema is used to generate a bunch of web services and the validation for all of them to pull that off, i need to be able to pass around tables
Andrii Sherman
As @bloberenober mentioned in #gold-sponsors channel - he can create code chunks for that and send you. Or make a PR in your repo directly and then explain all of them if needed which could be covered in "4x2 hours consultancy sessions" by assigning hours in calendly, that was shared with you
JT
JTOP2y ago
i get all that, but why are you explaining that rather than just telling me what the type would be? feel free to use my hours i'm sorry, i'm not meaning to sound so demanding. it's just that i'm trying to make a decision about what ORM to use for a massive project that i'm about to embark upon, and drizzle is at the top of the list. but it's useless to me if i can't actually use the objects it creates in a more complex way. prisma as a feature that can pull this off, which i was going to build from scratch, because I'm guessing you don't have it. They build a big model typemap, which you can then use generics to fetch from. It looks something like: TypeMap['model']['User']['create']['payload'] <--this bottom layer is equivalent to your InferModel<typeof usersTable, "insert"> i like drizzle way better than prisma for a lot of reasons, so i'm hoping i can find a way to make this app work.
Andrii Sherman
yeah, it definitely could be done with our types. We just need a bit of time to wrap it up for you Already late night here, so we may come back tomorrow with a solution
JT
JTOP2y ago
ok
Dan
Dan2y ago
@plainblackguy
how to pass a the mysql2 version of drizzle()
It's MySql2Database
and a model reference (the result of mysqlTable())
You can do type UsersTable = typeof usersTable
JT
JTOP2y ago
Wow, that seems almost too good to be true Thank you I’ll give it a shot I'm trying to do this:
await db.insert(table).values(props);
await db.insert(table).values(props);
Where props was passed in from a function with the type ModelMap[T]["insert"] which is itself the output of InferModel<table, 'insert'> I'm getting the following error:
Argument of type 'ModelMap[T]["insert"]' is not assignable to parameter of type 'MySqlInsertValue<ModelMap[T]["model"]>'.
Type '{ id: string; createdAt?: Date | undefined; updatedAt?: Date | undefined; username?: string | undefined; email?: string | undefined; realName?: string | undefined; password?: string | undefined; passwordType?: "bcrypt" | undefined; useAsDisplayName?: "username" | ... 2 more ... | undefined; admin?: boolean | undefin...' is not assignable to type 'MySqlInsertValue<ModelMap[T]["model"]>'.
Type '{ id: string; createdAt?: Date | undefined; updatedAt?: Date | undefined; username?: string | undefined; email?: string | undefined; realName?: string | undefined; password?: string | undefined; passwordType?: "bcrypt" | undefined; useAsDisplayName?: "username" | ... 2 more ... | undefined; admin?: boolean | undefin...' is not assignable to type 'MySqlInsertValue<ModelMap[T]["model"]>'.
Argument of type 'ModelMap[T]["insert"]' is not assignable to parameter of type 'MySqlInsertValue<ModelMap[T]["model"]>'.
Type '{ id: string; createdAt?: Date | undefined; updatedAt?: Date | undefined; username?: string | undefined; email?: string | undefined; realName?: string | undefined; password?: string | undefined; passwordType?: "bcrypt" | undefined; useAsDisplayName?: "username" | ... 2 more ... | undefined; admin?: boolean | undefin...' is not assignable to type 'MySqlInsertValue<ModelMap[T]["model"]>'.
Type '{ id: string; createdAt?: Date | undefined; updatedAt?: Date | undefined; username?: string | undefined; email?: string | undefined; realName?: string | undefined; password?: string | undefined; passwordType?: "bcrypt" | undefined; useAsDisplayName?: "username" | ... 2 more ... | undefined; admin?: boolean | undefin...' is not assignable to type 'MySqlInsertValue<ModelMap[T]["model"]>'.
This started happening when I changed my table type form any to your suggestion of typeof table I think this might be related to me not getting the right types on the able per our other discussion. now i can't find that discussion crap. let me start over with it
Dan
Dan2y ago
Hard to understand the underlying issue without seeing the types. Seems like an issue with how your types are implemented, not with Drizzle.
JT
JTOP2y ago
nope i found it: https://discord.com/channels/1043890932593987624/1085675996956590162 the problem is that i'm using a generator to create the table and you said i was going to need some generics and that's how i became a gold sponsor but then i became a gold sponsor and haven't gotten an answer on it yet (no blame, just think it got lost amongst our other questions)
Dan
Dan2y ago
Yeah, I was fixing the thing with the types from the other thread. I'll work on this one now.
JT
JTOP2y ago
so my generator put this out for example:
const UserTable: MySqlTableWithColumns<{
name: string;
columns: {
[x: string]: MySqlColumn<{
data: unknown;
driverParam: unknown;
notNull: boolean;
hasDefault: boolean;
tableName: string;
}>;
};
}>
const UserTable: MySqlTableWithColumns<{
name: string;
columns: {
[x: string]: MySqlColumn<{
data: unknown;
driverParam: unknown;
notNull: boolean;
hasDefault: boolean;
tableName: string;
}>;
};
}>
but for the exact same structure just writing it out by hand the type is:
const usersTemp: MySqlTableWithColumns<{
name: "users";
columns: {
id: MySqlColumn<{
data: string;
driverParam: string | number;
hasDefault: false;
notNull: true;
tableName: "users";
}>;
createdAt: MySqlColumn<{
data: Date;
driverParam: string | number;
hasDefault: true;
notNull: true;
tableName: "users";
}>;
... 8 more ...;
developer: MySqlColumn<...>;
};
}>
const usersTemp: MySqlTableWithColumns<{
name: "users";
columns: {
id: MySqlColumn<{
data: string;
driverParam: string | number;
hasDefault: false;
notNull: true;
tableName: "users";
}>;
createdAt: MySqlColumn<{
data: Date;
driverParam: string | number;
hasDefault: true;
notNull: true;
tableName: "users";
}>;
... 8 more ...;
developer: MySqlColumn<...>;
};
}>
thank you
Want results from more Discord servers?
Add your server