Define types for process.env in TypeScript

avatar
Borislav Hadzhiev

Last updated: Feb 29, 2024
3 min

banner

# Define types for process.env in TypeScript

To define types for process.env in TypeScript:

  1. Create an environment.d.ts file and declare types in the global namespace.
  2. Add properties to the ProcessEnv interface.
  3. Make the file a module by using export {}.

In the src directory of your project, create a types directory containing the following environment.d.ts file.

src/types/environment.d.ts
export {}; declare global { namespace NodeJS { interface ProcessEnv { DB_PORT: number; DB_USER: string; ENV: 'test' | 'dev' | 'prod'; } } }
The code for this article is available on GitHub

The example shows how to add typings for the DB_PORT, DB_USER and ENV properties on the process.env object.

Make sure to adjust the names of the properties according to your use case.

Now I can access the properties on the process.env object and get auto-completion.

index.ts
console.log(process.env.DB_USER); console.log(process.env.ENV); console.log(process.env.DB_PORT);

accessing process env properties in typescript

However, their values are undefined right now because we haven't set up a .env file yet.

# Add the path to your types to the typeRoots array

If you've tried restarting your IDE and still don't get autocompletion for the specified properties on the process.env object, try adding the path to your types directory to your tsconfig.json file.

tsconfig.json
{ "compilerOptions": { // ... rest "typeRoots": ["./node_modules/@types", "./src/types"] } }
The code for this article is available on GitHub

We used the export {} line in our environment.d.ts file to mark it as an external module.

A module is a file that contains at least 1 import or export statement. We are required to do that to be able to augment the global scope.

TypeScript looks for .d.ts files in the same places it looks for your regular .ts files. The location is determined by the include and exclude settings in your tsconfig.json file.

# Install the dotenv package

To add values for the specified properties on the process.env object, we need to install the dotenv package.

Open your terminal in the root directory of your project and run the following commands.

shell
npm install dotenv npm install -D @types/node

Now create a .env file in the root directory of your project.

.env
DB_PORT=9999 DB_USER=bobby_hadz ENV=test
Make sure to add the .env file to your .gitignore, especially if you work on a public repository.

In your index.ts file, before importing anything else, import and initialize the dotenv package.

index.ts
import 'dotenv/config'; console.log(process.env.DB_USER); // ๐Ÿ‘‰๏ธ "bobby_hadz" console.log(process.env.ENV); // ๐Ÿ‘‰๏ธ "test" console.log(process.env.DB_PORT); // ๐Ÿ‘‰๏ธ "9999"

initialize dotenv package

The code for this article is available on GitHub
You must load and initialize the dotenv package as the first thing in your index.ts file, especially if you have other files that need to access the environment variables.

If you import another file before initializing dotenv, you end up running the files before the properties are set on the process.env object.

Now restart your development server and you should see the properties on the process.env object print out the specified values.

process env properties success

Note that the DB_PORT property has a value of type string, even though we set it as a number in the .env file.

# Marking properties as optional

If you aren't sure whether a specific property on the process.env object will be populated, mark it as optional.

src:/types/environment.d.ts
export {}; declare global { namespace NodeJS { interface ProcessEnv { DB_PORT?: number; // ๐Ÿ‘ˆ๏ธ mark optional DB_USER: string; ENV: 'test' | 'dev' | 'prod'; } } }
The code for this article is available on GitHub

We marked the DB_PORT property as optional using a question mark.

This means that it will either be of the specified type or be undefined.

This is useful when you want to have to check if the property exists before you perform an operation in your code.

index.ts
console.log(process.env.DB_PORT || ''); // ๐Ÿ‘‰๏ธ "9999" or '', but not undefined

If you try to access a built-in method on an undefined value, you'd get a runtime error, so it's best to use optional properties when we aren't sure the property will be set.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev