type ValueType = 'string' | 'number' | 'boolean'; const prefix = 'Invariant failed'; // Throw an error if the condition fails // > Not providing an inline default argument for message as the result is smaller export function invariant( condition: any, // Can provide a string, or a function that returns a string for cases where // the message takes a fair amount of effort to compute message?: string | (() => string), ): asserts condition { if (condition) { return; } // Condition not passed // When not in production we allow the message to pass through // *This block will be removed in production builds* const provided: string | undefined = typeof message === 'function' ? message() : message; // Options: // 1. message provided: `${prefix}: ${provided}` // 2. message not provided: prefix const value: string = provided ? `${prefix}: ${provided}` : prefix; throw new Error(value); } export function ensureEnv(key: string): string; export function ensureEnv(key: string, valueType: 'string'): string; export function ensureEnv(key: string, valueType: 'number'): number; export function ensureEnv(key: string, valueType: 'boolean'): boolean; export function ensureEnv(key: string, valueType?: ValueType) { // eslint-disable-next-line no-process-env let value = process.env[key]; if (value === '') { value = undefined; } invariant(typeof value === 'string', `Missing "${key}" environment variable`); switch (valueType) { case 'number': return parseInt(value, 10); case 'boolean': return value === 'true'; default: return value; } }