I have following piece of code that pulls environment variables via dotenv, can substitute it, if it does not exist and defaultValue
is passed or throws error if neither of them contain value. This creates a scenario where execution either crashes or it returns valid value.
const getEnvironmentVariable = (
variable: string,
defaultValue?: string|number,
): string | number => {
if((process.env[variable] === undefined) && defaultValue === undefined){
// eslint-disable-next-line max-len
throw new Error(`Mandatory environment variable ${variable} was not set.`)
}
if(
process.env[variable] === undefined
&& defaultValue !== undefined
) {
// eslint-disable-next-line no-console, max-len
console.info(`Environment variable ${variable} was not set. Using default: ${defaultValue}`)
}
return process.env[variable] ?? defaultValue
}
But I am getting following error on return, even tho it will never happen, that undefined will be returned.
Type 'string | undefined' is not assignable to type 'string | number'. Type 'undefined' is not assignable to type 'string | number'.
CodePudding user response:
Typescript doesn't understand the concept of: "If this variable is undefined, it means that the other one is not."
To Typescript this just means the both of the variables can be undefined.
Another issue you might encounter is that process.env[variable]
will always return string | undefined
even though you checked in on a previous line. you should therefore store it in a const
. Here is an example that should work:
const getEnvironmentVariable = (
variable: string,
defaultValue?: string | number,
): string | number => {
const environmentVariable = process.env[variable]
if (environmentVariable === undefined) {
if (defaultValue === undefined) {
throw new Error(
`Mandatory environment variable ${variable} was not set.`,
);
}
console.info(
`Environment variable ${variable} was not set. Using default: ${defaultValue}`
);
return defaultValue;
}
return environmentVariable;
};
CodePudding user response:
After the first if
, defaultValue
is still string | number | undefined
because of the and
.
Since process.env[variable] === undefined
could be false, the second operand is not checked.
The same for the second if
, in order to check for defaultValue === undefined
you have to split the if
s:
const getEnvironmentVariable = (
variable: string,
defaultValue?: string|number,
): string | number => {
if(process.env[variable] === undefined) {
if(defaultValue === undefined) {
// eslint-disable-next-line max-len
throw new Error(`Mandatory environment variable ${variable} was not set.`)
}
if(defaultValue) {
console.info(`Environment variable ${variable} was not set. Using default: ${defaultValue}`)
return defaultValue;
}
}
return process.env[variable];
}