Environment Variables in TypeScript

In software development, environment variables allow you to define values that can change based on the environment your application is running in. For instance, you might have a different database connection string for development and production. TypeScript, being a superset of JavaScript, can make use of environment variables. This guide will help you understand how to work with them effectively.

Introduction to Environment Variables

Environment variables are key-value pairs that can affect how running processes behave on a computer. They're especially useful in the following scenarios:

  • Switching between development and production configurations.
  • Storing secrets that shouldn't be hardcoded.
  • Customizing behavior without modifying code.

Accessing Environment Variables

In Node.js (and by extension, TypeScript running in a Node environment), you can access environment variables using process.env.

const dbName = process.env.DATABASE_NAME;

Setting Environment Variables

Manually Setting

You can set environment variables directly in the terminal:

  • Unix-based systems (Linux & macOS):

    export DATABASE_NAME=my_database
  • Windows:

    set DATABASE_NAME=my_database

Using .env Files

A common practice is to store environment variables in a .env file.

Install the dotenv package to help load these variables:

npm install dotenv

Create a .env file in the root of your project:

DATABASE_NAME=my_database

Load the .env file in your TypeScript code:

import * as dotenv from 'dotenv'; dotenv.config(); const dbName = process.env.DATABASE_NAME;

Strong Typing Environment Variables

To leverage TypeScript's static typing with environment variables, you can define types for them.

interface Env { DATABASE_NAME: string; DATABASE_PORT?: number; } const myEnv: Env = { DATABASE_NAME: process.env.DATABASE_NAME || '', DATABASE_PORT: process.env.DATABASE_PORT ? parseInt(process.env.DATABASE_PORT) : undefined };

Type Safety with Type Guards

Ensure the presence and validity of specific environment variables using type guards:

if (!process.env.DATABASE_NAME) { throw new Error("DATABASE_NAME is not defined"); } if (process.env.DATABASE_PORT && isNaN(Number(process.env.DATABASE_PORT))) { throw new Error("DATABASE_PORT should be a number"); }

Using with Frontend Projects

If you're using TypeScript with frontend frameworks like React or Angular, bundlers like Webpack or Parcel might inline environment variables during the build process.

For example, with create-react-app, you can prefix environment variables with REACT_APP_ to make them available in your app:

REACT_APP_API_ENDPOINT=https://api.example.com

Then in your TypeScript:

const apiEndpoint = process.env.REACT_APP_API_ENDPOINT;

Note: Be cautious about which environment variables you expose to the frontend. Never expose sensitive data like API keys or secrets.

Tips and Best Practices

  • Default values: Provide default values for your environment variables to ensure your application behaves predictably.
  • Separate configs: Use different .env files for different environments, e.g., .env.development and .env.production.
  • Secrets: Never commit .env files containing secrets to version control. Add .env to .gitignore.

Further Reading

With this knowledge, you can effectively leverage environment variables in your TypeScript projects, making your applications more flexible and environment-aware.

Invite only

We're building the next generation of data visualization.