I have a function written in Typescript and I am looking to determine the return type based on the value retrieved from process.env.
For instance, the variables in my Node process.env can be strings, numbers, or booleans. I want to fetch them with their specific types without encountering any warnings or errors during compilation.
The compile time errors I encounter generally look like the one below, each corresponding to string, number, or boolean variations. The errors occur within the function where I'm seeing these issues:
Type 'string' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which might not correspond to 'string'.ts(2322)
In the simple function provided below, I face compile time errors. Is there a way to generically return these values?
function get<T>(envVar: string): T {
// Not fetching the actual value from process.env for this demonstration.
// If the process env value is a string, then return a string.
if (envVar === 's') {
return 'string value';
// compile error here: 2322
// Type 'string' is not assignable to type 'T'.
}
if (envVar === 'n') {
return 52;
// compile error here: 2322
// Type 'number' is not assignable to type 'T'.
}
if (envVar === 'b') {
return true;
// compile error here: 2322
// Type 'boolean' is not assignable to type 'T'.
}
return null;
}
Sample calling code:
// No compile errors. This is how I expect to use this function.
const s1: string = this.get<string>("s");
const n1: number = this.get<number>("n");
const b1: boolean = this.get<boolean>("b");
// Another approach without compile errors. Here, no explicit type is defined, hence it works.
const s2: string = this.get("s");
const n2: number = this.get("n");
const b2: boolean = this.get("b");
// Expected compile errors below.
// Type 'number' is not assignable to type 'string'.ts (2322)
const sN: string = this.get<number>("s");
// Type 'string' is not assignable to type 'number'.ts (2322)
const nS: number = this.get<string>("n");
Below is a pseudo-code example of what I ideally want to achieve, although uncertain if feasible in Typescript.
function get<T>(envVar: string): T {
// Obtain variable's value from process.env, always as a string
const val; // imagine val exists as a string
// Depending on T, return the appropriate type
if (T instanceof Number) {
return Number.parseInt(val) as T; // return as number
}
else if (T instancef Boolean) {
return Boolean.parse(val) as T; // return as boolean
}
else {
return val as T; // return as string
}
}
// Sample calling code:
const s1 = get<string>("key");
const n1 = get<number>("key");
const b1 = get<boolean>("key");
Upon further consideration, my main issue pertains to inferring the type "T" passed in and utilizing that information to handle returning an object of type "T".
Considering this, perhaps a more straightforward solution would be:
const s1 = get("key");
const n1 = getAsInt("key");
const b1 = getAsBoolean("key");