You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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_history
  • payment_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 21:32:33