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

NestJS中Drizzle ORM插入数据时TS2769类型匹配错误

解决NestJS + Drizzle ORM插入数据时的TS2769类型匹配错误

错误信息

TS2769: No overload matches this call.
Overload 1 of 2, '(values: (Insertable | Insertable[]) & { onConflict?: OnConflictBuilder | undefined; }): Promise<...>', gave the following error.
Type '{ customerSegment: string; ... }' is not assignable to type 'Insertable'.
Object literal may only specify known properties, and 'customerSegment' does not exist in type 'Insertable'.

相关代码片段

Drizzle生成的Schema(users表)

// drizzle/schema/users.ts
import { mysqlTable, varchar, int } from 'drizzle-orm/mysql-core';

export const users = mysqlTable('users', {
  id: int('id').primaryKey().autoincrement(),
  name: varchar('name', { length: 255 }).notNull(),
  customer_segment: varchar('customer_segment', { length: 50 }).notNull(),
});

export type InsertUser = typeof users.$inferInsert;

NestJS Service层代码

// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { db } from '../../drizzle/db';
import { users, InsertUser } from '../../drizzle/schema/users';

@Injectable()
export class UsersService {
  async createUser(userData: { name: string; customerSegment: string }) {
    // 此处触发TS2769错误
    const result = await db.insert(users).values(userData);
    return result;
  }
}

解决方法

1. 处理字段命名映射(驼峰 vs 蛇形)

这是最常见的原因:Drizzle默认保留数据库的蛇形命名(如customer_segment),但代码中使用驼峰命名(customerSegment),TypeScript会严格校验类型。

方法一:手动转换字段名

将传入的驼峰字段手动映射为数据库的蛇形字段:

async createUser(userData: { name: string; customerSegment: string }) {
  const mappedData = {
    name: userData.name,
    customer_segment: userData.customerSegment,
  };
  const result = await db.insert(users).values(mappedData);
  return result;
}

方法二:启用Drizzle驼峰自动转换

在Drizzle数据库配置中开启驼峰转换,自动处理命名映射:

// drizzle/db.ts
import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
import { users } from './schema/users';

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
});

// 启用casing: 'camelCase',自动将数据库蛇形字段映射为代码驼峰字段
export const db = drizzle(pool, {
  schema: { users },
  casing: 'camelCase',
});

开启后,InsertUser类型会自动生成为驼峰字段,Service层直接使用customerSegment即可,无需手动转换。

2. 修正类型推断与导入

确保使用正确的Drizzle推断类型:

  • 确认导入的InsertUser是从正确的schema文件导出的
  • 直接用InsertUser作为入参类型,提前校验传入数据:
async createUser(userData: InsertUser) {
  const result = await db.insert(users).values(userData);
  return result;
}

3. 过滤额外字段

如果传入的userData包含schema中未定义的字段,需过滤后再插入:

async createUser(userData: { name: string; customerSegment: string; extraField: string }) {
  // 只保留schema中存在的字段
  const filteredData = {
    name: userData.name,
    customer_segment: userData.customerSegment,
  };
  const result = await db.insert(users).values(filteredData);
  return result;
}

注:非必要不使用类型断言(如as unknown as InsertUser),会隐藏真实类型问题。

内容的提问来源于stack exchange,提问作者James Caranay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:13:23