So I wanted to create a simple TypeScript function which returns an environment variable, and depending on
whether it is required or not, it will:
- In the happy path, return the value as a
string - If the environment variable is not defined, either return a potentially
undefinedvalue (if not required) or throw an error (if required)
Sounds simple enough, right?
Well, the naive attempt will look something like this with some TypeScript magic:
Well, the naive attempt will look something like this with some TypeScript magic:
function getEnvVar<TReq extends boolean>(
envVarName: string,
required: TReq
): TReq extends true ? string : string | undefined {
const value = process.env[envVarName];
if (required && !value) {
throw new Error(`Missing environment variable: ${envVarName}`);
}
return value;
}
const required = getEnvVar("foo", true); // => string
const optional = getEnvVar("bar", false); // => string | undefined
This does not work, however (try it out in the TypeScript playground.
You will get the following error:
ERRORType 'string | undefined' is not assignable to type 'TReq extends true ? string : string | undefined'.
Type 'undefined' is not assignable to type 'TReq extends true ? string : string | undefined'.(2322)
Now, I honestly wish I could provide some solid type theory here and explain why the TypeScript type checker
cannot infer that the that the returned value can be
If you know, please reach out and let me know!
undefined, but I'm not sure why.If you know, please reach out and let me know!
