Define types for process.env in TypeScript


Borislav Hadzhiev

Mon Mar 21 20223 min read

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.

export {}; declare global { namespace NodeJS { interface ProcessEnv { DB_PORT: number; DB_USER: string; ENV: 'test' | 'dev' | 'prod'; } } }

The example above 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 autocompletion.

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

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

If you have 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.

{ "compilerOptions": { // ... rest "typeRoots": ["./node_modules/@types", "./src/types"] } }

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, which is determined by the include and exclude settings in your tsconfig.json file.

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:

npm install dotenv npm install -D @types/node

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

DB_PORT=9999 DB_USER=james_doe 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.

import 'dotenv/config'; console.log(process.env.DB_USER); // 👉️ "james_doe" console.log(process.env.ENV); // 👉️ "test" console.log(process.env.DB_PORT); // 👉️ "9999"
It's very important that you 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.

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

export {}; declare global { namespace NodeJS { interface ProcessEnv { DB_PORT?: number; // 👈️ mark optional DB_USER: string; ENV: 'test' | 'dev' | 'prod'; } } }

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.

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.

Use the search field on my Home Page to filter through my more than 1,000 articles.