typescriptbeginner

Type-Safe Configuration Loader

Load and validate configuration from environment variables with type coercion and required field checks.

typescript
function env(key: string, fallback?: string): string {
  const value = process.env[key] ?? fallback;
  if (value === undefined) {
    throw new Error(`Missing required env var: ${key}`);
  }
  return value;
}

function envInt(key: string, fallback?: number): number {
  const raw = process.env[key];
  if (raw === undefined) {
    if (fallback !== undefined) return fallback;
    throw new Error(`Missing required env var: ${key}`);
  }
  const parsed = parseInt(raw, 10);
  if (isNaN(parsed)) throw new Error(`${key} must be an integer, got: ${raw}`);
  return parsed;
}

function envBool(key: string, fallback?: boolean): boolean {
  const raw = process.env[key];
  if (raw === undefined) {
    if (fallback !== undefined) return fallback;
    throw new Error(`Missing required env var: ${key}`);
  }
  return ['true', '1', 'yes'].includes(raw.toLowerCase());
}

function envList(key: string, fallback?: string[]): string[] {
  const raw = process.env[key];
  if (raw === undefined) {
    if (fallback !== undefined) return fallback;
    throw new Error(`Missing required env var: ${key}`);
  }
  return raw.split(',').map(s => s.trim()).filter(Boolean);
}

// Build config object — fails fast on missing vars
function loadConfig() {
  return {
    app: {
      name: env('APP_NAME', 'my-app'),
      port: envInt('PORT', 3000),
      env: env('NODE_ENV', 'development') as 'development' | 'production' | 'test',
      debug: envBool('DEBUG', false),
    },
    db: {
      url: env('DATABASE_URL'),
      pool: envInt('DB_POOL_SIZE', 10),
    },
    redis: {
      url: env('REDIS_URL', 'redis://localhost:6379'),
    },
    cors: {
      origins: envList('CORS_ORIGINS', ['http://localhost:3000']),
    },
  } as const;
}

// Usage
try {
  const config = loadConfig();
  console.log(`Starting ${config.app.name} on :${config.app.port}`);
  console.log(`DB: ${config.db.url}`);
  console.log(`CORS origins: ${config.cors.origins.join(', ')}`);
} catch (err: any) {
  console.error(`Config error: ${err.message}`);
  process.exit(1);
}

Use Cases

  • Application configuration management
  • Environment-specific settings
  • Fail-fast startup validation

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.