How to Add Custom Types For NodeJS process.env in TypeScript

Robin
Updated on July 12, 2023

When we try to access our environment variables from process.env object in the Node.js and TypeScript application, we don't get auto-completion by default.

Because TypeScript has no idea what environment variables we have inside process.env object. But you can change this behavior by adding types to it.

How to Define Types To process.env For Auto-completion

These are the 3 simple steps to add types to environment variables (process.env) in Node.js application:

  • Step 1: Create a type declaration file.
  • Step 2: Extend process.env type by creating ProcessEnv interface.
  • Step 3: Include the type declaration file in the tsconfig.json file.

By doing so, TypeScript will know about your environment variables and get suggestions whenever you try to access them in your project.


Step 1: Creating a Type Declaration File

A type declaration file in TypeScript is a file that contains type information about JavaScript files. Usually, type declaration files end with .d.ts extensions.

It serves as a way to provide type annotations for existing JavaScript code that doesn't have explicit type information.

Therefore to create a type declaration file, you have to create a file that ends with .d.ts extension. You can give any name to this file, the name doesn't matter.

          |-- node_modules
|-- types
     |-- env.d.ts
|-- .env
|-- server.ts
|-- package-log.json
|-- package.json
|-- tsconfig.json
        

Here I am creating a env.d.ts file inside a types folder. This is the file structure of my project.


Step 2: Extending process.env with Custom Types

To add custom types to the process.env object you have to create ProcessEnv interface inside your type declaration file. You must name this interface as it is. A different name won't work.

It will contain all the environment variables. You have to declare it inside the NodeJS namespace.

          declare global {
    namespace NodeJS {
        interface ProcessEnv {
            API_KEY: string
            PORT?: number
            NODE_ENV: 'development' | 'production'
        }
    }
}

export {}
        

Declare a global NodeJS namespace in the env.d.ts file. This namespace will contain the ProcessEnv interface with all the environment variables.

I have added 3 properties to this interface: API_KEY, PORT, and NODE_ENV

Because I have these 3 environment variables in my .env file. You have to include all of your variables in this way.

You can also make environment variables optional by adding "?" at the end of their names. Here, the PORT is an optional variable.

Don'f forget to export an empty object. It will make this file as a module. Without it, this interface won't work.

Also Read: Power of declare Keyword in TypeScript: Complete Guide


Step 3: Connecting The Declaration File with Node.js

Creating the declaration file and adding ProcessEnv interface won't add types to the process.env object. You also have to let TypeScript know about it.

You can connect this file to TypeScript by adding its path in the tsconfig.json file.

          {
    "compilerOptions": {
        // ...
        "typeRoots": ["types/env.d.ts", "node_modules/@types"]
    }
}
        

Add the path of your type declaration file in the typeRoots array along with the @types folder from the node_modules folder.

Congratulations, you have successfully added your custom types for process.env object. Now you will get auto-completion from TypeScript for your environment variables.

Also Read: Add Properties in TypeScript Based on Another Property Value


Loading and Using Type-Safe Environment Variables

You have to load environment variables to a Node.js project to access them from the process.env object. You have to use the dotenv package for this.

Install dotenv package with the following command:

          npm install --save dotenv
        

Now you have to import and initialize this package to load .env file to your project.

          import 'dotenv/config'

console.log(process.env.NODE_ENV)
// production
        

You can import and initialize this package using import 'dotenv/config' in your TypeScript file. This will load your .env file from the root of your project by default.

Now whenever you want to access your environment variables from process.env object, TypeScript will give you suggestions.

Also Read: TypeScript Type vs. Interface: Which One Should You Use?


Handling Undefined and Optional Environment Variables

If you declare any of your environment variables as optional, you should perform if checks before using their values in production. Otherwise, you might get errors if they are not available or undefined.

TypeScript could show your error messages if you try to access optional values without using any check.

          import 'dotenv/config'

if (process.env.PORT) {
    console.log(process.env.PORT)
    // 3000
}
        

Here the PORT environment variable is optional. Therefore, I am checking if this variable has any value or not using the if statement.

          const PORT = process.env.PORT || 3000

console.log(PORT)
// 3000
        

You can also set default values for your optional variables. Here I am setting 3000 as default if the process.env.PORT is undefined.

That's it. This is how you can add types for your environment variable in TypeScript for your Node.js project. You will get type safety and auto-completion from TypeScript.

Also Read: Mastering Type Guards in TypeScript: Making Your Code Safer

Related Posts