Summary
On main (f1e9c37) a statically typed drizzle database object throws on its first call:
TypeError: Cannot convert undefined or null to object
at <anonymous>
The same program with const db: any = drizzle(pool, { mode: "default" }) runs fine, and db.session.execute(q) / db.session.prepareQuery(...).execute() work either way. perry 0.5.1519 runs the typed form. Found while reproducing #9356; it blocks that issue's repro script on main.
Reproduction
npm i drizzle-orm@0.44.7 mysql2@3.24.2, a MySQL on 127.0.0.1:
import mysql from "mysql2/promise";
import { drizzle } from "drizzle-orm/mysql2";
import { sql } from "drizzle-orm";
const pool = mysql.createPool({ host: "127.0.0.1", port: 3306, user: "root", password: "", database: "test" });
const db = drizzle(pool, { mode: "default" }); // typed: MySql2Database & { $client }
try {
await db.execute(sql`SELECT 1 AS x`); // TypeError on main
console.log("ok");
} catch (e) { console.log(String(e)); }
| toolchain |
const db = drizzle(...) (typed) |
const db: any = drizzle(...) |
| 0.5.1519 (23a2113) |
ok |
ok |
| main f1e9c37 |
TypeError: Cannot convert undefined or null to object |
ok |
db.transaction(async (tx) => …) fails the same way. db.session.execute(q), db.session.prepareQuery(dialect.sqlToQuery(q), undefined, undefined, false).execute(), Object.keys(db), Object.keys(db.session) all succeed on main with the typed object, so the failure is in how the typed db.execute / db.transaction member call is lowered (the return type of drizzle() is an intersection MySql2Database<TSchema> & { $client: … }), not in drizzle's own code. Same TypeError with compilePackages: ["drizzle-orm"] set.
A second variant: in a pnpm layout (node_modules/drizzle-orm -> ../../../node_modules/.pnpm/drizzle-orm@0.44.7_…/node_modules/drizzle-orm, the reporter's app tree) even the db: any form throws the same TypeError on both toolchains, so module resolution changes which drizzle build gets compiled there. Both variants are perrymaster-reproducible (/root/claude-9356/repro/drz2.ts and /root/claude-9356/intree/).
Where
Bisect list (313 commits, 23a2113..f1e9c37); the typed-dispatch commits in that range are the obvious first suspects: #9479 (root the dynamic-dispatch receiver across its argument list), #9472 (static this is the constructor), #9444 (accessor call must not corrupt the caller's this).
Summary
On
main(f1e9c37) a statically typed drizzle database object throws on its first call:The same program with
const db: any = drizzle(pool, { mode: "default" })runs fine, anddb.session.execute(q)/db.session.prepareQuery(...).execute()work either way.perry 0.5.1519runs the typed form. Found while reproducing #9356; it blocks that issue's repro script on main.Reproduction
npm i drizzle-orm@0.44.7 mysql2@3.24.2, a MySQL on 127.0.0.1:const db = drizzle(...)(typed)const db: any = drizzle(...)TypeError: Cannot convert undefined or null to objectdb.transaction(async (tx) => …)fails the same way.db.session.execute(q),db.session.prepareQuery(dialect.sqlToQuery(q), undefined, undefined, false).execute(),Object.keys(db),Object.keys(db.session)all succeed on main with the typed object, so the failure is in how the typeddb.execute/db.transactionmember call is lowered (the return type ofdrizzle()is an intersectionMySql2Database<TSchema> & { $client: … }), not in drizzle's own code. Same TypeError withcompilePackages: ["drizzle-orm"]set.A second variant: in a pnpm layout (
node_modules/drizzle-orm -> ../../../node_modules/.pnpm/drizzle-orm@0.44.7_…/node_modules/drizzle-orm, the reporter's app tree) even thedb: anyform throws the same TypeError on both toolchains, so module resolution changes which drizzle build gets compiled there. Both variants are perrymaster-reproducible (/root/claude-9356/repro/drz2.tsand/root/claude-9356/intree/).Where
Bisect list (313 commits, 23a2113..f1e9c37); the typed-dispatch commits in that range are the obvious first suspects: #9479 (root the dynamic-dispatch receiver across its argument list), #9472 (static
thisis the constructor), #9444 (accessor call must not corrupt the caller'sthis).