fetchenv-ts
The TypeScript friendly environment variable getter
Why?
All process.env[var]
values are string
or undefined
by default. This package allows you to define TypeScript types for it easily, and ensure types are converted correctly out the other end, so happy TypeScript intellisense!
Installation
npm i --save fetchenv-ts
or
yarn add fetchenv-ts
Usage
Types
Possible types (for conversion) are:
export enum TYPES {
STRING = "string",
NUMBER = "number",
FLOAT = "float",
ARRAY_STRING = "string_array",
ARRAY_NUMBER = "number_array",
ARRAY_FLOAT = "float_array",
BOOLEAN = "boolean",
CUSTOM = "custom",
}
When using the CUSTOM
type, you must also define a customConverter
function to be used when processing (see below)
Config
When using configureEnv
, you pass in an EnvConfig
-shape object, of type:
type EnvConfig<T> = {
[key in keyof T]: EnvConfigVar;
};
type EnvConfigVar = {
type: TYPES;
isOptional?: boolean;
customConverter?: (val: string) => unknown;
};
When using TYPES.CUSTOM
as the type
, you must also define the transformation function in customConverter
, which will be used when processing that key.
You must also define the TypeScript-side of the equation, as you would any other object:
interface EnvShape {
SOME_ENVIRONMENT_VAR: number;
}
You can see the code example below for usage in-situ.
Code Example
First, configure your environment:
import { configureEnv, TYPES } from "fetchenv-ts";
interface EnvShape {
SOME_STRING: string;
NODE_ENV: "development" | "production";
PORT: number;
MIGHT_NOT_EXIST?: boolean;
SOME_STRING_ARRAY: string[];
SOME_NUMBER_ARRAY: number[];
SOME_FLOAT_ARRAY: number[];
SOME_FLOAT: number;
DEFINITE_BOOLEAN: boolean;
MULTIPLY_BY_TWO: number;
}
export const fetchEnv = configureEnv<EnvShape>({
SOME_STRING: { type: TYPES.STRING },
NODE_ENV: { type: TYPES.STRING },
PORT: { type: TYPES.NUMBER },
MIGHT_NOT_EXIST: { type: TYPES.BOOLEAN, isOptional: true },
SOME_STRING_ARRAY: { type: TYPES.ARRAY_STRING },
SOME_NUMBER_ARRAY: { type: TYPES.ARRAY_NUMBER },
SOME_FLOAT_ARRAY: { type: TYPES.ARRAY_FLOAT },
SOME_FLOAT: { type: TYPES.FLOAT },
DEFINITE_BOOLEAN: { type: TYPES.BOOLEAN },
MULTIPLY_BY_TWO: {
type: TYPES.CUSTOM,
isOptional: true,
customConverter: (x) => parseInt(x, 10) * 2,
},
});
Now across your code, you can use:
import { fetchEnv } from "./configure";
process.env.SOME_STRING = "https://somestring.com";
process.env.NODE_ENV = "development";
process.env.PORT = "1234";
process.env.SOME_STRING_ARRAY = "dave,tom,james";
process.env.SOME_NUMBER_ARRAY = "1,2,3";
process.env.SOME_FLOAT_ARRAY = "1.23,4.56,7.89";
process.env.SOME_FLOAT = "1.429";
process.env.DEFINITE_BOOLEAN = "true";
process.env.MULTIPLY_BY_TWO = "5";
const url = fetchEnv("SOME_STRING");
const env = fetchEnv("NODE_ENV");
const port = fetchEnv("PORT");
const notAllowed = fetchEnv("MIGHT_NOT_EXIST");
const someStringArray = fetchEnv("SOME_STRING_ARRAY");
const someNumberArray = fetchEnv("SOME_NUMBER_ARRAY");
const someFloatArray = fetchEnv("SOME_FLOAT_ARRAY");
const someFloat = fetchEnv("SOME_FLOAT");
const definiteBoolean = fetchEnv("DEFINITE_BOOLEAN");
const shouldBeTen = fetchEnv("MULTIPLY_BY_TWO");
console.log(url, typeof url);
console.log(env, typeof env);
console.log(port, typeof port);
console.log(notAllowed, typeof notAllowed);
console.log(someStringArray, typeof someStringArray);
console.log(someNumberArray, typeof someNumberArray);
console.log(someFloatArray, typeof someFloatArray);
console.log(someFloat, typeof someFloat);
console.log(definiteBoolean, typeof definiteBoolean);
console.log(shouldBeTen, typeof shouldBeTen);
Limitations
Due to the inability to inspect TypeScript types within your code in a nice way, unfortunately the "double-defining" has to exist (ie you must define the TypeScript interface for your environment, as well as the env config object using TYPES.[type]
).