Skip to content

Instantly share code, notes, and snippets.

@jhbabon
Created September 18, 2020 08:08
Show Gist options
  • Save jhbabon/4814ba2b06d4bdf000533851848f903b to your computer and use it in GitHub Desktop.
Save jhbabon/4814ba2b06d4bdf000533851848f903b to your computer and use it in GitHub Desktop.
A small environment variables parser in TypeScript
import { env } from 'process'
function isNumber(n: unknown): n is number {
if (typeof n !== 'number' || Number.isNaN(n)) {
return false
}
return true
}
function parseNumber(value: string): number {
const num = Number(value)
if (isNumber(num)) {
return num
}
throw new Error(`The value '${value}' is not a number`)
}
function parseNumbers(value: string): number[] | undefined {
return value.split(',').map(parseNumber)
}
/**
* Define the env vars and their expected type
*/
export interface EnvVars {
// List of numbers
BUCKETS: number[]
// Just a string
NAME: string
// Just a number
PORT: number
}
type Undefinable<T> = {
[K in keyof T]: T[K] | undefined
}
/**
* Define the env vars parser based on the EnvVars type
*
* The parser must make sure that the values are returned as the proper type
*/
const parser: Undefinable<EnvVars> = {
get BUCKETS(): number[] | undefined {
try {
const value = env['BUCKETS']
if (!value) {
return undefined
}
return parseNumbers(value)
} catch (e) {
throw new Error(`Error parsing env var BUCKETS: ${e.message}`)
}
},
get NAME(): string | undefined {
return env['NAME']
},
get PORT(): number | undefined {
try {
const value = env['PORT']
if (!value) {
return undefined
}
return parseNumber(value)
} catch (e) {
throw new Error(`Error parsing env var PORT: ${e.message}`)
}
},
}
/**
* Extract the env var parsed to its correct type or return the default value if not found
*
* If you try to get an env var that is not defined or assign it to the wrong type, the type system will complain
*/
export function envVar<K extends keyof EnvVars>(name: K, defaultValue: EnvVars[K]): EnvVars[K] {
return parser[name] ?? defaultValue
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment