Reputation: 572
I was trying to created a cached mongoose connection for Next.js + Typescript app, but using:
let cached = global.mongoose;
if (!cached) {
cached = global.mongoose = { conn: null, promise: null };
}
global.mongoose is showing the following Error:
Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.ts(7017)
EDIT:
here's full /lib/dbConnect.ts
file
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;
Upvotes: 3
Views: 3111
Reputation: 1
Adding onto Alisson Leal's answer, declaring mongoose as follows seems to be working for me:
// the namespace conflicts, so import as 'mg'
import { default as mg } from 'mongoose';
declare global {
var mongoose: {
conn: null | typeof mg;
promise: null | Promise<typeof mg>;
};
}
Upvotes: 0
Reputation: 109
Quick and easy solution!
This connection file is based on an official Next.Js example on GitHub.
The project is able to connect to mongodb using the mongoose library. However, he does not provide an example of how to do this in TypeScript. But easily you can convert the example code which will work normally without any hassle of needing to declare types in utils/global.d.ts
and so on.
1 First install mongoose and its flavors.
To install "mongoose" in a TypeScript project in Next.js, follow these steps:
1 - Open the terminal at the root of your project.
2 - Run the following command to install "mongoose":
# if you are using npm
npm install mongoose
# if you are using yarn
yarn add mongoose
3 - Run the following command to install the "mongoose" types:
# se estiver usando npm
npm install --save-dev @types/mongoose
# se estuver usando yarn
yarn add --dev @types/mongoose
2 Create the TypeScript connection file dbConnect.ts
.
import mongoose from 'mongoose';
const MONGODB_URI: string | any = 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 as any).mongoose;
if (!cached) {
cached = (global as any).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) => {
console.log('Connected to database!');
return mongoose;
});
}
try {
cached.conn = await cached.promise;
} catch (e) {
cached.promise = null;
throw e;
}
return cached.conn;
}
export default dbConnect;
Upvotes: 0
Reputation: 86
As Prisma link:
Create a new file 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
In tsconfig.json add to include:
...
"include": ["next-env.d.ts", "utils/global.d.ts", "**/*.ts", "**/*.tsx"],
...
The 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
Untested
Upvotes: 0
Reputation: 194
Since you're technically extending the global context, you need to add its new types.
I usually have a custom.d.ts
in the root folder for packages that don't have types.
In your case:
declare global {
const mongoose: any
}
Also, don't forget to add custom.d.ts
in tsconfig.json
:
{
"compilerOptions": {...},
"include": ["...your other files", "custom.d.ts"],
}
reference with Prisma connection: https://stackoverflow.com/a/69434850/14122260
Upvotes: 2
Reputation: 1643
I don't see anything particularly wrong in your file, maybe check if your file is in the right directory, also your .env.local
file.
This is the lib/dbConnect.js
I used in my previous project just for your reference.
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
Upvotes: 0