How to define typescript types for process.env to have auto-completion
👋🏻 For a French version of this article 🇫🇷 : let’s check out at my blog : https://modern-javascript.fr/comment-definir-les-types-de-process-env-avec-typescript-pour-avoir/ By default when you…
👋🏻 For a English version of this article 🇺🇸 : let’s check out at Medium

Utiliser la fonction process.env pour consommer des variables d'environnement dans son programme NodeJS est très fréquent, c'est d'ailleurs une bonne pratique des « Twelve-Factor App» — un manifeste pour concevoir des applications qui se mettent à l'échelle automatiquement—.

Par défaut quand vous installez les types ambiants TS de NodeJS (@types/node) dans votre projet javascript, les types de process.env sont définis comme tels :

interface Process extends EventEmitter {
  emitWarning(warning: string | Error, name?: string, ctor?: Function): void;
  env: ProcessEnv;
  exit(code?: number): never;
}

interface ProcessEnv {
  [key: string]: string | undefined;
}
Que faut-il comprendre ici ?

Et bien on voit que l'objet process possède une propriété env de type ProcessEnv (une interface). Cette interface est composée d'un objet ayant des clés sous forme de string et des valeurs string ou non définies.

Super ! Le compilateur typescript ne criera pas si vous tapez process.env.HOST par contre, vous êtes obligés d'aller voir les variables d'environnement injectée pour savoir quelles variables sont disponible à l'utilisation.

Vous en conviendrez : il y a mieux comme expérience de développement.

Typescript permet de surcharger des définitions ambiantes d'un autre module très simplement en utilisant un concept nommé fusion d'interfaces (interfaces merging), grâce à cela nous allons pouvoir définir en amont la représentation des valeurs disponibles dans process.env.

Surcharger les définitions de process dans NodeJS afin d'avoir de l'autocompletion

Dans un fichier que j'appelle modules.d.ts nous allons définir les choses suivantes.

Attention : Ce module doit être dans le scope du projet défini dans le tsconfig afin que le compilateur le trouve et le prenne en compte

declare namespace NodeJS {
  export interface ProcessEnv {
    HOST: string;
    DB_URL: string;
    DB_NAME?: string;
  }
}

Désormais, votre compilateur et IDE devrait vous proposer de l'autocompletion et une bonne validation.