I have a bunch of places in my code where I rely on an environment variable and want to throw an error if it does not exist:
if(!process.env.SOME_VAR) {
throw new Error('Missing required environment variable "SOME_VAR"');
}
doSomethingWithVar(process.env.SOME_VAR);
// function doSomethingWithVar(var: string);
I was wondering if there was a way to utilize TypeScript's asserts
-keyword to write a function to do the assertion for me? Something like
function assertEnvironmentVariable<T extends string>(name: T):
asserts NodeJS.ProcessEnv[name] is string {
if(!process.env[name]) {
throw new Error(`Missing required environment variable "${name}"`);
}
}
// Usage:
assertEnvironmentVariable('SOME_VAR');
// no type error here since `assertEnvironmentVariable` already made sure it exists
doSomethingWithVar(process.env.SOME_VAR);
However, this definition of assertEnvironmentVariable
does not work - is this possible at all?
CodePudding user response:
A simple solution without using asserts
would be:
function getEnvironmentVariable(name: string): string {
const value = process.env[name];
if(!value) {
throw new Error(`Missing required environment variable "${name}"`);
}
return value;
}
const value = getEnvironmentVariable("SOME_VAR");
doSomethingWithVar(value);
CodePudding user response:
Yes you just need to change how you're asserting:
function assertEnvironmentVariable(name: string | number): asserts name is keyof typeof process.env {
// If you're going to assert a type, you should probably actually
// assert the type of the thing.
if (typeof process.env[name] !== 'string' || !process.env[name]) {
// You don't *have* to use a TypeError, but it makes sense
throw new TypeError(`Missing required environment variable ${name}`);
}
}
assertEnvironmentVariable('someVar');
console.log(process.env.someVar); // No type error
I think that should get you there. Note that like a type predicate this is you saying to the compiler "hey I'm verifying this at runtime" meaning that it's on you to actually make sure you're checking what you think you are.