Type 'undefined' is not assignable to type 'string | string[]'

Viewed 7618

I am just trying to config the .env file on my main file.

but somehow it's not working but the error is wrong, its showing undefined but its already there

1st try

require('dotenv').config({ path: `${__dirname}/../.env` })

2nd try

import * as dotenv from 'dotenv'
dotenv.config()

3rd try

import 'dotenv/config'

somehow the .env is not loading.

executing the file by

ts-node main.ts

.env file

SESSION_SECRET = uq07nyvn4xadskdg
COOKIE_SECRET = 0k5kb4qi8shhi7u0n

DB_HOST = 127.0.0.1
DB_PORT = 3306
DB_USER = root
DB_PASS = root
DB_NAME = db_name

database connection

export const db = createPool({
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  user: process.env.DB_USER,
  password: process.env.DB_PASS,
  database: process.env.DB_NAME,
})

session

const sessionD = session({
  secret: process.env.SESSION_SECRET,
  resave: true,
  saveUninitialized: true,
  store: new MySQLStore({
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    user: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: process.env.DB_NAME,
  }),
})
3 Answers

dotenv doesn't tell typescript anything. All it does it put whatever is in your .env into process.env at runtime. This doesn't change any types of anything.

So you're dealing with process.env that seems to have this type:

export interface ProcessEnv {
    [key: string]: string | undefined;
}

Which means you can't assign it to a value that can't be undefined.

const myVar: string = process.env.WHATEVER
// Type 'string | undefined' is not assignable to type 'string'.
//   Type 'undefined' is not assignable to type 'string'.

The fix is to handle the undefined case. What if someone forgets the .env file or removes some its entries? What should your code do in that case?

Perhaps, provide a default:

const whatever: string = process.env.WHATEVER ?? 'whatever default'

Or maybe throw an error:

let whatever: string
if (process.env.WHATEVER) {
  whatever = process.env.WHATEVER
} else {
  throw new Error("WHATEVER environment variable is not set")
}

TL;DR: Handle the undefined case.

This worked for me in 2022:

I suggest you create a type declaration for your variables. Name it env.d.ts and save it with the following content in your source directory, e. g. /src

declare namespace NodeJS {
  interface ProcessEnv {
    readonly SESSION_SECRET: string
    readonly COOKIE_SECRET: string
    readonly DB_HOST: string
    readonly DB_PORT: string
    readonly DB_USER: string
    readonly DB_PASS: string
    readonly DB_NAME: string
  }
}

NB: Port is a string because dotenv handles everything as string

Now make sure the env.d.ts is included in the include section in your tsconfig.json (pseudocode - ... stands for your other properties:

{
  ...,
  "include": [
    "src/**/*.d.ts",
  ]
}

Now the variables should be recognized by typescript.

The types expected are string or string array, and you are passing environment variables that are not recognizable by the typescript. So you have to typecast your environment variable as a string like this for all your .env variables and the error will be removed.

secret: process.env.SESSION_SECRET as string;

You can read about Type assertion here.

Related