What is the best way to implement dotenv in a TypeScript project?

Attempting to load .env environment variables using Typescript.

Here are my .env and app.ts files:

//.env

DB_URL=mongodb://127.0.0.1:27017/test
// app.ts

import * as dotenv from 'dotenv';
import express from 'express';
import mongoose from 'mongoose';

dotenv.config();
mongoose.connect(process.env.DB_URL, config);

When running the app.ts with the ts-node src/app.ts command, an error is thrown:

Unable to compile TypeScript:
src/app.ts:50:18 - error TS2769: No overload matches this call.
  Overload 1 of 3, '(uris: string, callback: (err: MongoError) => void): Promise<typeof import("mongoose")>', gave the following error.
    Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
      Type 'undefined' is not assignable to type 'string'.
  Overload 2 of 3, '(uris: string, options?: ConnectionOptions | undefined): Promise<typeof import("mongoose")>', gave the following error.
    Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
      Type 'undefined' is not assignable to type 'string'.

50 mongoose.connect(process.env.DB_URL, config);

However, adding the following if statement resolves the issue:

//app.ts
import * as dotenv from 'dotenv';
import express from 'express';
import mongoose from 'mongoose';

dotenv.config();

//Add this code
if (!process.env.DB_URL) {
  process.exit(1);
}

mongoose.connect(process.env.DB_URL, config);
Example app listening at http://localhost:3000
Mongoose default connection is open to mongodb://127.0.0.1:27017/test

The question remains: why does this error not occur in the code below?

Answer №1

After analyzing the error message, it becomes evident that TypeScript expects the first parameter of mongoose.connect() to be a string, whereas environment variables can either be a string or undefined.

Introducing the condition helps in ensuring that process.env.DB_URL is not undefined when calling

mongoose.connect(process.env.DB_URL, config)

If there is certainty that it will never be undefined, leveraging TypeScript's Non-null assertion operator is recommended

mongoose.connect(process.env.DB_URL!, config);

Recommendation:

Rather than

import * as dotenv from 'dotenv';
...
dotenv.config();

You may proceed with the following approach

import 'dotenv/config'

This practice ensures that environment variables are configured prior to subsequent import statements, simplifying the process by executing this step only once in the main file of your application.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for passing a function and an object to a functional component in React

I am struggling with TypeScript and React, so please provide clear instructions. Thank you in advance for your help! My current challenge involves passing both a function and an object to a component. Let's take a look at my component called WordIte ...

Attain the ability to distinguish errors in Promises

Context In my project, I have implemented a REST API that interacts with MongoDB using Node.js and Express. The issue at hand involves handling errors based on different scenarios when making requests to the NoSQL database. Challenge The current impleme ...

Retrieve the http method used in a controller within an Express.js application

I am currently working on creating a registration form using passport-local for authentication and forms as the form helper. Since the registration process only utilizes GET and POST methods, I am aiming to consolidate all handling into one function. In ...

Nesting objects within arrays using Typescript Generics

Hello, I am currently attempting to assign the correct type to an object with nested values. Here is a link to the code in the sandbox: https://codesandbox.io/s/0tftsf interface Product { name: string, id: number productList?:ProductItem[] } interf ...

Employing async await for postponing the execution of a code block

I have been working on an Angular component where I need to perform some actions after a data service method returns some data asynchronously. Although I attempted to use async/await in my code, I feel that I may not have fully understood how it works. Her ...

"Using Jest to specifically test the functionality of returning strings within an object

Attempting to run a jest test, it seemed like the issue was with the expect, toBe section as I believed that the two objects being compared (data, geonames) were exactly the same. However, upon closer inspection, they turned out to be different. The struct ...

Performing multiple asynchronous operations on a set of data using node.js

Currently, I am in the process of developing a nodejs application and I am still learning about nodejs's asynchronous model. The issue at hand is that I have made changes to a database collection by adding a string field while still referencing anoth ...

Working with Nested Array Data in C# Using MongoDB

I am new to working with MongoDB in a C# context. Let's consider the following sample documents: [ { "Number": "2140007529", "Name": "ABC", "IsInactive": true, "EntryList": [ { "Timestamp ...

Combining two authentication tokens in a single endpoint

I'm facing a challenge where I need to combine 2 authentication tokens in one endpoint - the user and admin tokens - to access all merchants. Despite trying various solutions suggested on stackoverflow, none seem to work for me. Below are my code sni ...

Accessing a MongoDB cluster within a Kubernetes environment

I am struggling with connecting to the MongoDB replica and service created in my Terraform configuration. Specifically, I cannot connect to MongoDB using the CLI and the cluster domain name. locals { labels = { "app" = "mongo" } ...

What is the reason for the regeneration of the 2D array?

I have a method called generateWeights() that retrieves random values in an array; And a method named learn() that calls the changeWeights() method to alter the values in the array. Expected: Prior to invoking the learn() method, I anticipate receiving an ...

How come TypeScript doesn't recognize my MongoDB ObjectID as a valid type?

Currently, I am working with Node.js, MongoDB, and TypeScript. The code snippet below is error-free: const ObjectID = require("mongodb").ObjectID; const id = new ObjectID("5b681f5b61020f2d8ad4768d"); However, upon modifying the second line as follows: ...

Ways to insert script tag in a React/JSX document?

private get mouseGestureSettingView() { const {selectedMenu} = this.state; return ( selectedMenu == 2 ? <script src="../../assets/js/extensions/mouse-gesture/options.js"></script> <div className={styles.settingForm}& ...

What is the best way to execute my mocha fixtures with TypeScript?

I am seeking a cleaner way to close my server connection after each test using ExpressJS, TypeScript, and Mocha. While I know I can manually add the server closing code in each test file like this: this.afterAll(function () { server.close(); ...

I'm having difficulty updating the Angular CLI version

I am currently running Angular CLI version 7.1.4 and I have been attempting to update to the latest version. However, each time I try to update, I encounter a multitude of errors. I have attempted using the command ng update @angular/core @angular/cli b ...

Potential memory leak caused by Elasticsearch client in Node.js

Working on my web application involves utilizing the node Elasticsearch client along with testing using the rest client. When I conducted a test by sending a request through postman test runner with 1000 iterations, I noticed an increase in memory usage. ...

Backend data not displaying on HTML page

I am currently working on an Angular 8 application where I have a service dedicated to fetching courses from an API endpoint. The service method that I'm using looks like this: loadCourseById(courseId: number) { return this.http.get<Cours ...

Exploring an array of objects to find a specific string similar to the one being

I recently developed a TypeScript code snippet that searches for objects in a list by their name and surname, not strictly equal: list = list.filter( x => (x.surname + ' ' + x.name) .trim() .toLowerCase() .sear ...

After refreshing, the other items stored locally are lost once a new item is added

After refreshing the page, only the item added remains and the rest are lost. How can I make sure all items persist? Here is my code snippet: let buttonsDom = document.querySelectorAll(elementsStr.itemsBtn) const buttons = [... buttonsDom] window.addEven ...

What is the best way to indicate that, out of a total of three fields, at least one field must be

Within my MongoDB schema, there are a total of 3 fields required. Every document that gets inserted into this collection needs to have a minimum of one of those 3 fields present. Is there a way to define this requirement in the validation process? ...