Drizzle中外键引用触发类型错误问题咨询
Drizzle Schema 循环依赖导致的类型错误问题
在Drizzle Schema中,users和payment_history为一对多关系(一个用户对应多条支付记录)。添加额外的last_payment双向关系后,引用payment_history.id时抛出类型错误:
Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
表定义
users表
export const users = pgTable("users",{ id: varchar("id").primaryKey().unique().notNull(), phone_number: varchar("phone_number", {length: 13 }).unique().notNull(), subscribed: boolean("subscribed").default(false), on_trial: boolean("onTrial").default(false), trial_start: timestamp("trial_start"), trial_end: timestamp("trial_end"), plan_id: integer("plan_id").references(()=>plan.id, { onDelete: "cascade" }), // 外键关联plan.id // 关联支付记录表的最后一笔支付ID last_payment_id: varchar("last_payment_id").references(() => payment_history.id, { onDelete: "cascade" }), last_payment_timestamp: timestamp("last_payment_timestamp"), // 最后一笔支付的时间戳 created_at: timestamp("created_at").defaultNow(), agreement_to_terms: boolean("agreement_to_terms").default(false), sms_permission: boolean("sms_permission").default(false), user_type: user_type("user_type"), has_onboarded: boolean("has_onboarded").default(false).notNull(), })
payment_history表
export const payment_history = pgTable("payment_history",{ id: varchar("id").primaryKey().unique().notNull(), order_id: varchar("order_id").notNull(), amount: integer("amount"), signature: varchar("signature"), plan_id: integer("plan_id").references(()=>plan.id, { onDelete: "cascade" }), // 外键关联plan.id date_of_payment: timestamp("date_of_payment"), user_id: varchar("user_id").references(() => users.id, { onDelete: "cascade" }), // 外键关联users.id })
初始关系定义
users表关系
export const userRelation = relations(users, ({ one, many }) => ({ business: many(business_detail), individual: many(individual_detail), payment_history: many(payment_history), // 被注释的last_payment关系 // last_payment: one(payment_history, { // fields: [users.last_payment_id], // references: [payment_history.id], // }), plan: one(plan, { fields: [users.plan_id], references: [plan.id], }), device_information: one(device_information, { fields: [users.id], references: [device_information.user_id], }), document_details: many(document_details), credit_trans: many(credit_trans), }))
payment_history表关系
export const paymentHistoryRelations = relations(payment_history, ({ one, many }) => ({ user: one(users, { fields: [payment_history.user_id], references: [users.id], }), last_payment: one(users, { fields: [payment_history.user_id], references: [users.last_payment_id], }), plan: one(plan, { fields: [payment_history.plan_id], references: [plan.id], }), }))
导致问题的新增关系定义
payment_history表新增关系
export const paymentHistoryRelations = relations(payment_history, ({ one, many }) => ({ user: one(users, { fields: [payment_history.user_id], references: [users.id], }), last_payment: one(users, { fields: [payment_history.user_id], references: [users.last_payment_id], }), // 其他原有关系... }))
users表新增关系
export const userRelation = relations(users, ({ one, many }) => ({ // 其他原有关系... payment_history: many(payment_history), last_payment: one(payment_history, { fields: [users.last_payment_id], references: [payment_history.id], }), // 其他原有关系... }))
问题分析与解决方案
问题原因
错误源于双向循环依赖:
users表通过last_payment_id关联payment_history.id,同时在关系中通过last_payment反向关联payment_historypayment_history在关系中通过last_payment关联users.last_payment_id,形成闭环,导致TypeScript无法正确推断类型,抛出隐式any错误。
解决办法
移除逻辑不合理的循环关系:删除paymentHistoryRelations中的last_payment关联(一条支付记录仅属于一个用户,无需反向关联用户的last_payment_id),保留合理的单向关联即可。
修改后的paymentHistoryRelations:
export const paymentHistoryRelations = relations(payment_history, ({ one, many }) => ({ user: one(users, { fields: [payment_history.user_id], references: [users.id], }), // 移除last_payment关联 plan: one(plan, { fields: [payment_history.plan_id], references: [plan.id], }), }))
保留users表中正确的last_payment关系:
export const userRelation = relations(users, ({ one, many }) => ({ business: many(business_detail), individual: many(individual_detail), payment_history: many(payment_history), last_payment: one(payment_history, { fields: [users.last_payment_id], references: [payment_history.id], }), plan: one(plan, { fields: [users.plan_id], references: [plan.id], }), device_information: one(device_information, { fields: [users.id], references: [device_information.user_id], }), document_details: many(document_details), credit_trans: many(credit_trans), }))
调整后循环依赖被打破,TypeScript可正确推断类型,错误将消失。
内容的提问来源于stack exchange,提问作者Crade47
相关产品推荐
相关产品推荐

