使用`let cached = global.mongoose`时出现Next.js + Typescript + mongoose错误

Posted

技术标签:

【中文标题】使用`let cached = global.mongoose`时出现Next.js + Typescript + mongoose错误【英文标题】:Next.js + Typescript + mongoose error when using `let cached = global.mongoose` 【发布时间】:2021-12-04 10:56:31 【问题描述】:

我试图为 Next.js + Typescript 应用程序创建一个缓存的猫鼬连接,但使用的是:

let cached = global.mongoose;

if (!cached) 
  cached = global.mongoose =  conn: null, promise: null ;

global.mongoose 显示以下错误:

Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.ts(7017)

编辑: 这是完整的/lib/dbConnect.ts 文件

import mongoose,  Connection  from "mongoose";

const MONGODB_URI: string = process.env.MONGODB_URI!;

if (!MONGODB_URI) 
  throw new Error(
    "Please define the MONGODB_URI environment variable inside .env.local"
  );


let cached = global.mongoose;

if (!cached) 
  cached = global.mongoose =  conn: null, promise: null ;


async function dbConnect() 
  if (cached.conn) 
    return cached.conn;
  

  if (!cached.promise) 
    const opts = 
      bufferCommands: false,
    ;

    cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => 
      return mongoose;
    );
  
  cached.conn = await cached.promise;
  return cached.conn;


export default dbConnect;

【问题讨论】:

把整个lib/dbConnect.js文件贴出来吧,我不认为错误是由你上面的代码引起的。 好的,添加了整个文件的代码 您发现问题了吗?我也有同样的问题 【参考方案1】:

由于您在技术上扩展了全局上下文,因此您需要添加它的新类型。

对于没有类型的包,我通常在根文件夹中有一个custom.d.ts

在你的情况下:

declare global 
  const mongoose: any

另外,不要忘记在tsconfig.json 中添加custom.d.ts


  "compilerOptions": ...,
  "include": ["...your other files", "custom.d.ts"],

Prisma 连接参考:https://***.com/a/69434850/14122260

【讨论】:

我遇到了类似的问题,尽管我在 custom.d.ts 中定义了这个答案,但我仍然得到 Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature. @madmanali93 您是否在tsconfig.json 内的“包含”设置中包含“custom.d.ts”? 是的,我做了它仍然没有工作。我最终引用了 primsa 链接并只是强制转换(全局)以寻求解决方法。不知道为什么会这样。【参考方案2】:

作为 Prisma 链接:

创建一个新文件 utils/global.d.ts

import  Connection  from 'mongoose'

declare global 
    var mongoose: any


export const mongoose = global.mongoose || new Connection()

if (process.env.NODE_ENV !== 'production') global.mongoose = mongoose

在 tsconfig.json 中添加包含:

...
"include": ["next-env.d.ts", "utils/global.d.ts", "**/*.ts", "**/*.tsx"],
...

dbConnect.js:

import mongoose from 'mongoose'

const MONGODB_URI : string = process.env.MONGODB_URI || ''

if (!MONGODB_URI) 
    throw new Error(
        'Please define the MONGODB_URI environment variable inside .env.local'
    )


/**
 * Global is used here to maintain a cached connection across hot reloads
 * in development. This prevents connections growing exponentially
 * during API Route usage.
 */
let cached = global.mongoose

if (!cached) 
    cached = global.mongoose =  conn: null, promise: null 


async function dbConnect() 
    if (cached.conn) 
        return cached.conn
    

    if (!cached.promise) 
        const opts = 
            bufferCommands: false,
        


        cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => return mongoose);
    
    cached.conn = await cached.promise
    return cached.conn


export default dbConnect

未经测试

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案3】:

我在您的文件中没有发现任何特别错误,也许检查您的文件是否在正确的目录中,以及您的 .env.local 文件。 这是我在上一个项目中使用的lib/dbConnect.js,仅供参考。

import mongoose from 'mongoose';

const MONGODB_URI = process.env.MONGODB_URI;

if (!MONGODB_URI) 
  throw new Error(
    'Please define the MONGODB_URI environment variable inside .env.local';
  )


let cached = global.mongoose;

if (!cached) 
  cached = global.mongoose =  conn: null, promise: null 


async function dbConnect () 
  if (cached.conn) 
    return cached.conn
  

  if (!cached.promise) 
    const opts = 
      useNewUrlParser: true,
      useUnifiedTopology: true,
      bufferCommands: false,
      bufferMaxEntries: 0,
      useFindAndModify: true,
      useCreateIndex: true
    

    cached.promise = mongoose.connect(MONGODB_URI, opts).then(mongoose => 
      return mongoose
    )
  
  cached.conn = await cached.promise
  return cached.conn


export default dbConnect

【讨论】:

请注意,我使用的是 Typescript,而不是 javascript

以上是关于使用`let cached = global.mongoose`时出现Next.js + Typescript + mongoose错误的主要内容,如果未能解决你的问题,请参考以下文章

Vue开发环境安装和配置

条件jQuery实现

swift清理缓存

方案:何时使用 let、let* 和 letrec? [复制]

258 关键字let

使用 Let's Encrypt 保护 GitLab 页面得到 404