Environment variables are really quite useful. From being able to debug and test different environments on your local machine, to having code that will behave differently on staging and production servers without having to keep multiple code bases.
Interesting Tip: Code that adapts and changes itself on the fly is called polymorphic code.
Cast as Boolean
So lets propose you want to have a boolean in your code that may change when ran in any given environment. You might start with something like this:
const myEnvironmentVariable: boolean = process.env.MY_ENV_VAR;
If you’re using typescript and have your tsconfig correctly configured, then you will likely get one of these two errors:
- “This condition will always return ‘false’ since the types ‘string | undefined’ and ‘boolean’ have no overlap”.
- “Type ‘string | undefined’ is not assignable to type ‘boolean’. Type ‘undefined’ is not assignable to type ‘boolean’. ts(2322)”
How do we go about fixing this without using some hack like type any?
const myEnvironmentVariable: boolean = process.env.MY_ENV_VAR == null ? false : process.env.MY_ENV_VAR === 'true';
For those who perhaps haven’t seen this before, what you are looking at is called a ternary operator. In essence, it’s just a short hand if statement. what we’re saying here is that if the environment variable doesn’t exist, then it’s false otherwise set it to true.
We can check here to see the typeof and assigned values:
process.env.MY_ENV_VAR = 'true'; const myEnvironmentVariable: boolean = process.env.MY_ENV_VAR == null ? false : process.env.MY_ENV_VAR === 'true'; const myEnvironmentVariable2: boolean = process.env.MY_ENV_VAR2 == null ? false : process.env.MY_ENV_VAR2 === 'true'; console.log(typeof(myEnvironmentVariable), myEnvironmentVariable); // outputs 'boolean true' console.log(typeof(myEnvironmentVariable2), myEnvironmentVariable2); // outputs 'boolean false'
Cast as String
Following the same process as above, lets declare a new variable from our environment.
const url: string = process.env.URL;
Here we will get the error
- Type ‘string | undefined’ is not assignable to type ‘string’.
Type ‘undefined’ is not assignable to type ‘string’.ts(2322)
Fixing this is easier than with the boolean as null or undefined will still be allowed and let us check if the variable has been set. We can use type casting here.
const url: string = process.env.URL as string;
Parse to Number
const expiresInTime: number = process.env.EXPIRES_TIME;
Type ‘string | undefined’ is not assignable to type ‘number’.
Type ‘undefined’ is not assignable to type ‘number’.ts(2322)
We can follow the same fix as with type string by casting it as a number.
const expiresInTime: number = process.env.EXPIRES_TIME as number;
This now produces another error unfortunatly. The error occurs because TypeScript will not allow you to implicitly cast from type string to type number. Here is the error we encounter.
- Conversion of type ‘string | undefined’ to type ‘number’ may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to ‘unknown’ first.
Type ‘string’ is not comparable to type ‘number’.ts(2352)
Parsing the string as an integer will solve this problem for us. We also need to add a type cast of type string inside the parseInt function parameter however.
const expiresInTime: number = parseInt(process.env.EXPIRES_TIME as string);