No type inference when specifying a reference.

Hi, I am trying out Drizzle for my application, and I am having some issues when I have a table that has a one-to-one and one-to-many relation on another table. I have the following schema:
import { relations } from 'drizzle-orm';
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';

export const invitations = sqliteTable('invitations', {
id: integer('id').primaryKey({ autoIncrement: true }).notNull(),
status: text('status', { enum: ['ACCEPTED', 'REJECTED'] }).notNull(),
email: text('email').unique().notNull(),
notes: text('notes'),
primaryGuestId: integer('primary_guest_id').notNull(),
});

export const invitationsRelations = relations(invitations, ({ one, many }) => ({
primaryGuest: one(guests, { relationName: 'primaryGuest', fields: [invitations.primaryGuestId], references: [guests.id] }),
guests: many(guests),
}));

export const guests = sqliteTable('guests', {
id: integer('id').primaryKey({ autoIncrement: true }).notNull(),
firstName: text('first_name').notNull(),
lastName: text('last_name').notNull(),
invitationId: integer('invitation_id').notNull().references(() => invitations.id),
});

export const guestsRelations = relations(guests, ({ one }) => ({
invitation: one(invitations, { fields: [guests.invitationId], references: [invitations.id] }),
}));
import { relations } from 'drizzle-orm';
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';

export const invitations = sqliteTable('invitations', {
id: integer('id').primaryKey({ autoIncrement: true }).notNull(),
status: text('status', { enum: ['ACCEPTED', 'REJECTED'] }).notNull(),
email: text('email').unique().notNull(),
notes: text('notes'),
primaryGuestId: integer('primary_guest_id').notNull(),
});

export const invitationsRelations = relations(invitations, ({ one, many }) => ({
primaryGuest: one(guests, { relationName: 'primaryGuest', fields: [invitations.primaryGuestId], references: [guests.id] }),
guests: many(guests),
}));

export const guests = sqliteTable('guests', {
id: integer('id').primaryKey({ autoIncrement: true }).notNull(),
firstName: text('first_name').notNull(),
lastName: text('last_name').notNull(),
invitationId: integer('invitation_id').notNull().references(() => invitations.id),
});

export const guestsRelations = relations(guests, ({ one }) => ({
invitation: one(invitations, { fields: [guests.invitationId], references: [invitations.id] }),
}));
Which generates the following SQL:
CREATE TABLE `guests` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`first_name` text NOT NULL,
`last_name` text NOT NULL,
`invitation_id` integer NOT NULL,
FOREIGN KEY (`invitation_id`) REFERENCES `invitations`(`id`) ON UPDATE no action ON DELETE no action
);
--> statement-breakpoint
CREATE TABLE `invitations` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`status` text NOT NULL,
`email` text NOT NULL,
`notes` text,
`primary_guest_id` integer NOT NULL
);
--> statement-breakpoint
CREATE UNIQUE INDEX `invitations_email_unique` ON `invitations` (`email`);
CREATE TABLE `guests` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`first_name` text NOT NULL,
`last_name` text NOT NULL,
`invitation_id` integer NOT NULL,
FOREIGN KEY (`invitation_id`) REFERENCES `invitations`(`id`) ON UPDATE no action ON DELETE no action
);
--> statement-breakpoint
CREATE TABLE `invitations` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`status` text NOT NULL,
`email` text NOT NULL,
`notes` text,
`primary_guest_id` integer NOT NULL
);
--> statement-breakpoint
CREATE UNIQUE INDEX `invitations_email_unique` ON `invitations` (`email`);
3 Replies
Jon Koops
Jon KoopsOP6mo ago
This is all fine, until I want to add a reference from primary_guest_id to the guest id. If I change the following line:
primaryGuestId: integer('primary_guest_id').notNull(),
primaryGuestId: integer('primary_guest_id').notNull(),
to:
primaryGuestId: integer('primary_guest_id').notNull().references(() => guests.id),
primaryGuestId: integer('primary_guest_id').notNull().references(() => guests.id),
Now suddenly the ORM is no longer able to infer a TypeScript type (both invitations and guests are any, and I get the following errors:
'invitations' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
'guests' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
'invitations' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
'guests' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
It seems however that Drizzle kit is able to create the SQL:
CREATE TABLE `guests` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`first_name` text NOT NULL,
`last_name` text NOT NULL,
`invitation_id` integer NOT NULL,
FOREIGN KEY (`invitation_id`) REFERENCES `invitations`(`id`) ON UPDATE no action ON DELETE no action
);
--> statement-breakpoint
CREATE TABLE `invitations` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`status` text NOT NULL,
`email` text NOT NULL,
`notes` text,
`primary_guest_id` integer NOT NULL,
FOREIGN KEY (`primary_guest_id`) REFERENCES `guests`(`id`) ON UPDATE no action ON DELETE no action
);
--> statement-breakpoint
CREATE UNIQUE INDEX `invitations_email_unique` ON `invitations` (`email`);
CREATE TABLE `guests` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`first_name` text NOT NULL,
`last_name` text NOT NULL,
`invitation_id` integer NOT NULL,
FOREIGN KEY (`invitation_id`) REFERENCES `invitations`(`id`) ON UPDATE no action ON DELETE no action
);
--> statement-breakpoint
CREATE TABLE `invitations` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`status` text NOT NULL,
`email` text NOT NULL,
`notes` text,
`primary_guest_id` integer NOT NULL,
FOREIGN KEY (`primary_guest_id`) REFERENCES `guests`(`id`) ON UPDATE no action ON DELETE no action
);
--> statement-breakpoint
CREATE UNIQUE INDEX `invitations_email_unique` ON `invitations` (`email`);
Why are my TypeScript types getting borked? How can this be fixed? I have a feeling this is a circular reference issue, as when I remove the .references(() => invitations.id), from invitationId this all seems to work.
Jon Koops
Jon KoopsOP6mo ago
GitHub
[BUG]: Circular reference causes type to become any · Issue #2476...
What version of drizzle-orm are you using? 0.31.2 What version of drizzle-kit are you using? 0.22.6 Describe the Bug When two tables reference each other in a circular manner the types of the table...
Jon Koops
Jon KoopsOP6mo ago
Hmmm, upon closer inspection I need a seperate table to link both together, so perhaps what I am doing here is invalid.
Want results from more Discord servers?
Add your server