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

Nuxt3中Nitro插件的Drizzle ORM类型推断实现问询

解决Nuxt3 + Drizzle Nitro插件的类型推断问题

核心思路

通过显式定义Drizzle数据库实例类型并扩展Nitro的上下文类型,让TypeScript能正确识别event.context.$database的类型。

步骤1:定义Schema与DB类型

先将你的数据库Schema抽离到单独文件,并生成对应的Drizzle数据库类型:

// server/database/schema.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';

// 示例Schema,替换成你的实际表结构
export const users = sqliteTable('users', {
  id: integer('id').primaryKey(),
  name: text('name').notNull(),
});

// 导出所有Schema集合
export const schemas = { users };

// 生成具体的DB类型(根据你用的数据库驱动调整,比如PostgreSQL用PostgresDatabase)
export type DB = BetterSQLite3Database<typeof schemas>;

步骤2:扩展Nitro上下文类型

在项目根目录创建类型声明文件,扩展Nitro的NitroEventContext接口:

// types/nitro.d.ts
import type { DB } from '~/server/database/schema';

declare module 'nitropack' {
  interface NitroEventContext {
    $database: DB;
  }
}

// 确保TypeScript识别该文件
export {};

步骤3:修改Nitro插件代码

在插件中显式指定db的类型为我们定义的DB:

// server/plugins/database.ts
import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';
import { migrate } from 'drizzle-orm/better-sqlite3/migrator';
import type { DB } from '~/server/database/schema';
import { schemas } from '~/server/database/schema';

export default defineNitroPlugin(async (nitroApp) => {
  const sqlite = new Database('sqlite.db');
  // 显式指定db的类型为DB
  const db: DB = drizzle(sqlite, { schema: schemas });
  
  migrate(db, { migrationsFolder: 'server/database/migrations' });

  nitroApp.hooks.hook('request', (event) => {
    event.context.$database = db;
  });
});

效果验证

现在在API路由中使用event.context.$database时,TypeScript会自动推断出完整的类型,比如event.context.$database.users会包含你定义的表结构、查询方法等类型提示。

注:如果使用PostgreSQL等其他数据库驱动,只需替换对应的导入和类型(比如PostgresDatabase)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:37:07