使用drizzle-orm插入PostgreSQL时遇No Overload Matches This Call错误
错误信息
No overload matches this call.
Overload 1 of 2, '(value: { title: string | SQL| Placeholder<string, any>; content: string | SQL | Placeholder<string, any>; }): PgInsertBase<PgTableWithColumns<{ name: "posts"; schema: undefined; columns: { ...; }; dialect: "pg"; }>, NodePgQueryResultHKT, undefined, false, never>', gave the following error.
Object literal may only specify known properties, and 'authorId' does not exist in type '{ title: string | SQL| Placeholder<string, any>; content: string | SQL | Placeholder<string, any>; }'.
问题场景
使用Node.js结合Drizzle-ORM向PostgreSQL插入数据时,插入关联users表的posts数据,TypeScript报错不识别外键字段authorId,但表结构中已明确定义该字段。
表结构定义
import { integer, pgTable, text, timestamp, varchar } from "drizzle-orm/pg-core"; import { usersTable } from "./users.schema"; export const posts = pgTable("posts", { id: integer().primaryKey().generatedAlwaysAsIdentity(), title: varchar({ length: 255 }).notNull(), content: text("content").notNull(), created: timestamp().defaultNow(), authorId: integer().references(() => usersTable.id) // 外键关联users表id });
插入代码
import { drizzle, NodePgDatabase } from "drizzle-orm/node-postgres"; import { Pool } from "pg"; import * as schema from "./schema/schema"; import "dotenv/config"; import { faker } from "@faker-js/faker"; import { randomInt } from "crypto"; const pool = new Pool({ connectionString: process.env.DATABASE_URL, ssl: true }) const db = drizzle(pool, { schema }) as NodePgDatabase<typeof schema>; async function main() { const userIds = await Promise.all( Array(50).fill("").map(async () => { const user = await db.insert(schema.usersTable).values({ email: faker.internet.email(), name: faker.person.fullName(), age: randomInt(1, 70) }).returning(); return user[0].id; }) ); const postIds = await Promise.all( Array(50).fill("").map(async () => { const post = await db.insert(schema.posts).values({ title: faker.lorem.sentence(5), content: faker.lorem.paragraph(), authorId: faker.helpers.arrayElement(userIds), // 随机选择用户ID }).returning(); return post[0].id; }) ); }
问题核心
TypeScript无法自动推断posts表中的authorId字段类型,导致插入操作时提示该字段不存在,尽管表结构已正确定义外键关联。
解决方案
1. 检查Schema导出与导入一致性
确认posts表在./schema/schema文件中正确导出,且主文件中导入的schema.posts确实指向包含authorId字段的最新表定义,避免因旧定义缓存导致类型不匹配。
2. 移除手动类型断言
主文件中对db的as NodePgDatabase<typeof schema>手动断言可能覆盖Drizzle自动生成的精确类型,建议移除断言,让Drizzle自动推断:
// 替换原db定义 const db = drizzle(pool, { schema });
3. 升级Drizzle-ORM版本
部分旧版本Drizzle-ORM存在外键类型推断bug,升级到最新稳定版本可解决该问题:
npm update drizzle-orm drizzle-kit
4. 显式指定插入值类型(临时方案)
若上述方法无效,可通过satisfies关键字显式指定插入值类型,强制TypeScript识别authorId:
const post = await db.insert(schema.posts).values({ title: faker.lorem.sentence(5), content: faker.lorem.paragraph(), authorId: faker.helpers.arrayElement(userIds), } satisfies typeof schema.posts.$inferInsert).returning();
内容的提问来源于stack exchange,提问作者Inexpli

