Skip to content

Commit 3f776aa

Browse files
dmealingclaude
andauthored
fix(codegen-ts): emit type-only Drizzle symbols with import type (verbatimModuleSyntax) (#165) (#166)
The default entityFile() output imported Drizzle's type-only symbols as VALUE imports: InferSelectModel / InferInsertModel (drizzle-orm) and AnyPgColumn / AnySQLiteColumn (the *-core package, used only as a .references() return-type annotation). Under `verbatimModuleSyntax: true` — a common default in modern Vite/TS app templates — tsc rejects each with TS1484 ("… is a type and must be imported using a type-only import"), so a generated DAO fails `tsc -b` with hundreds of errors even though it runs fine under a bundler. Mark the three symbols type-only via ts-poet's `t:` prefix (the idiom already used for FastifyInstance/Hono/TPH imports), so they emit as `import type` (or an inline `type` modifier when mixed with value imports from the same module). This fixes both the built-in generator and the ADR-0034 scaffold-and-own reference template, which delegates to the same renderDrizzleSchema / renderInferredTypes primitives. Adds a real-tsc compile guard with verbatimModuleSyntax ON over an entity with a self-referential FK (so AnyPgColumn is exercised); a negative control confirms it catches the TS1484 regression for all three symbols. Golden snapshots updated (the only change is value→type imports). TS-only; codegen output, no metamodel or cross-port impact. Claude-Session: https://claude.ai/code/session_01Ew1XfYSbEAezxjs9opynAe Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent a0fa3a5 commit 3f776aa

25 files changed

Lines changed: 226 additions & 42 deletions

server/typescript/packages/codegen-ts/src/templates/drizzle-schema.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,9 @@ function renderColumn(
344344
// initializer") under `strict`. The annotation is a harmless explicit supertype
345345
// for acyclic FKs, so emitting it unconditionally is safe.
346346
const anyColType = ctx.dialect === "sqlite" ? "AnySQLiteColumn" : "AnyPgColumn";
347-
const anyColSym = imp(`${anyColType}@${spec.importModule}`);
347+
// Used only as a return-type annotation → type-only import (t:) so it emits
348+
// `import type` and doesn't fail tsc under `verbatimModuleSyntax` (TS1484). (#165)
349+
const anyColSym = imp(`t:${anyColType}@${spec.importModule}`);
348350
if (fkInfo.targetEntityName === currentEntityName) {
349351
// Self-referential FK (e.g. createdBy → this same table): reference the local
350352
// table const directly — NOT a self-import.

server/typescript/packages/codegen-ts/src/templates/inferred-types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ export function renderInferredTypes(entity: MetaObject, tphBase = false, ctx?: R
5757
// ctx is optional for bare unit-test calls — those fall back to the default
5858
// always-pluralize spelling.
5959
const varName = ctx ? ctx.collectionName(entity.name) : variableNameFromEntity(entity.name);
60-
const selectSym = imp("InferSelectModel@drizzle-orm");
61-
const insertSym = imp("InferInsertModel@drizzle-orm");
60+
// Type-only symbols (t: prefix) so ts-poet emits `import type` — otherwise a
61+
// value import of these types fails tsc under `verbatimModuleSyntax` (TS1484). (#165)
62+
const selectSym = imp("t:InferSelectModel@drizzle-orm");
63+
const insertSym = imp("t:InferInsertModel@drizzle-orm");
6264
const docs = renderDocsFor(entity);
6365
const docsPrefix = docs ? `${docs}\n` : "";
6466
const rowName = tphBase ? `${entity.name}Row` : entity.name;

server/typescript/packages/codegen-ts/test/golden/__snapshots__/package/Tag.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Tag (Tag)
33
// Customize via Tag.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel, relations } from "drizzle-orm";
54
import {
6-
AnySQLiteColumn,
5+
type InferInsertModel,
6+
type InferSelectModel,
7+
relations,
8+
} from "drizzle-orm";
9+
import {
10+
type AnySQLiteColumn,
711
integer,
812
sqliteTable,
913
text,

server/typescript/packages/codegen-ts/test/golden/__snapshots__/package/shop/commerce/Order.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Order (shop::commerce::Order)
33
// Customize via Order.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel, relations } from "drizzle-orm";
5-
import { AnySQLiteColumn, integer, sqliteTable } from "drizzle-orm/sqlite-core";
4+
import {
5+
type InferInsertModel,
6+
type InferSelectModel,
7+
relations,
8+
} from "drizzle-orm";
9+
import {
10+
type AnySQLiteColumn,
11+
integer,
12+
sqliteTable,
13+
} from "drizzle-orm/sqlite-core";
614
import { z } from "zod";
715
import { customers } from "../users/Customer";
816
import { products } from "./Product";

server/typescript/packages/codegen-ts/test/golden/__snapshots__/package/shop/commerce/Product.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Product (shop::commerce::Product)
33
// Customize via Product.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel, relations } from "drizzle-orm";
54
import {
6-
AnySQLiteColumn,
5+
type InferInsertModel,
6+
type InferSelectModel,
7+
relations,
8+
} from "drizzle-orm";
9+
import {
10+
type AnySQLiteColumn,
711
integer,
812
sqliteTable,
913
text,

server/typescript/packages/codegen-ts/test/golden/__snapshots__/package/shop/users/Customer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Customer (shop::users::Customer)
33
// Customize via Customer.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel } from "drizzle-orm";
4+
import type { InferInsertModel, InferSelectModel } from "drizzle-orm";
55
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
66
import { z } from "zod";
77

server/typescript/packages/codegen-ts/test/golden/__snapshots__/postgres/Exercise.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Exercise (Exercise)
33
// Customize via Exercise.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel, relations } from "drizzle-orm";
54
import {
6-
AnyPgColumn,
5+
type InferInsertModel,
6+
type InferSelectModel,
7+
relations,
8+
} from "drizzle-orm";
9+
import {
10+
type AnyPgColumn,
711
bigint,
812
bigserial,
913
integer,

server/typescript/packages/codegen-ts/test/golden/__snapshots__/postgres/Program.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Program (Program)
33
// Customize via Program.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel } from "drizzle-orm";
4+
import type { InferInsertModel, InferSelectModel } from "drizzle-orm";
55
import {
66
bigserial,
77
boolean,

server/typescript/packages/codegen-ts/test/golden/__snapshots__/postgres/Purchase.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Purchase (Purchase)
33
// Customize via Purchase.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel, relations } from "drizzle-orm";
54
import {
6-
AnyPgColumn,
5+
type InferInsertModel,
6+
type InferSelectModel,
7+
relations,
8+
} from "drizzle-orm";
9+
import {
10+
type AnyPgColumn,
711
bigint,
812
bigserial,
913
integer,

server/typescript/packages/codegen-ts/test/golden/__snapshots__/postgres/Subscriber.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @generated by @metaobjectsdev/codegen-ts — DO NOT EDIT.
22
// Source metadata: Subscriber (Subscriber)
33
// Customize via Subscriber.extra.ts in this directory.
4-
import { InferInsertModel, InferSelectModel } from "drizzle-orm";
4+
import type { InferInsertModel, InferSelectModel } from "drizzle-orm";
55
import {
66
bigserial,
77
boolean,

0 commit comments

Comments
 (0)