Comment typer les variables d'environnement en TypeScript
Vous avez écrit process.env.API_KEY pour la centième fois, et TypeScript continue de le typer comme string | undefined. Votre IDE n’offre aucune autocomplétion. Pire encore, vous avez déployé en production pour découvrir qu’une variable manquante a fait planter votre application. Les variables d’environnement TypeScript méritent une meilleure gestion que cela.
Ce guide vous montre comment ajouter la sécurité des types aux variables d’environnement dans les projets frontend modernes et full-stack—couvrant à la fois import.meta.env pour les configurations basées sur Vite et process.env pour les contextes Node.
Points clés à retenir
- Les applications navigateur utilisent l’injection au moment de la compilation (variables intégrées dans les bundles), tandis que Node.js lit les variables d’environnement à l’exécution—cette distinction affecte à la fois les stratégies de sécurité et de typage.
- Utilisez les déclarations
ImportMetaEnvpour les projets Vite et l’augmentationNodeJS.ProcessEnvpour les contextes Node afin d’obtenir l’autocomplétion IDE et la vérification des types. - Les types TypeScript seuls ne peuvent pas empêcher les plantages à l’exécution—validez toujours les variables d’environnement requises au démarrage en utilisant des vérifications simples ou des bibliothèques de schémas comme Zod.
- Ne mettez jamais de secrets dans des variables préfixées (
VITE_,NEXT_PUBLIC_) car celles-ci deviennent visibles dans les bundles côté client.
Comprendre les variables d’environnement au moment de la compilation vs. à l’exécution
Avant de typer quoi que ce soit, comprenez une distinction critique : les applications navigateur et les serveurs gèrent les variables d’environnement différemment.
Injection au moment de la compilation (applications navigateur) : Des outils comme Vite remplacent les références aux variables d’environnement par les valeurs réelles pendant la compilation. Les variables n’existent pas à l’exécution—elles sont intégrées dans votre bundle JavaScript.
Variables d’environnement à l’exécution (côté serveur) : Node.js lit process.env depuis l’environnement système réel lorsque votre code s’exécute. Les valeurs peuvent changer entre les déploiements sans recompilation.
Cette distinction est importante pour la sécurité. Toute variable injectée au moment de la compilation devient visible dans votre code côté client. C’est pourquoi les frameworks utilisent des règles d’exposition basées sur des préfixes—Vite n’expose que les variables commençant par VITE_, et Next.js expose les variables côté client avec le préfixe NEXT_PUBLIC_. Les clés privées sans ces préfixes restent uniquement côté serveur.
Typer import.meta.env dans les projets Vite
Vite utilise import.meta.env au lieu de process.env. Pour ajouter des variables d’environnement type-safe en TypeScript, créez un fichier de déclaration :
// env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
// ajoutez plus de variables ici
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
Maintenant TypeScript fournit l’autocomplétion et traite ces variables comme string plutôt que string | undefined. Placez ce fichier dans votre répertoire src et assurez-vous que votre tsconfig.json l’inclut.
Typer ProcessEnv pour les contextes Node.js
Pour le code côté serveur ou les outils utilisant process.env, augmentez l’interface NodeJS.ProcessEnv :
// globals.d.ts
declare namespace NodeJS {
interface ProcessEnv {
DATABASE_URL: string
API_SECRET: string
NODE_ENV: 'development' | 'production' | 'test'
}
}
Cette approche vous donne l’autocomplétion dans toute votre base de code. L’exemple NODE_ENV montre que vous pouvez utiliser des types union pour les variables avec des valeurs possibles connues.
Discover how at OpenReplay.com.
Pourquoi les types seuls ne suffisent pas
Voici le piège : la fusion de déclarations indique à TypeScript ce qui devrait exister, pas ce qui existe réellement. Vous avez typé DATABASE_URL comme string, mais si quelqu’un oublie de la définir, votre application plante à l’exécution.
Les types TypeScript sont effacés au moment de la compilation. Ils ne peuvent pas valider que les variables d’environnement existent réellement lorsque votre code s’exécute.
Valider les variables d’environnement au démarrage
Pour valider les variables d’environnement en TypeScript, vérifiez-les tôt—avant que votre application ne fasse quoi que ce soit d’important. Une approche simple :
// config.ts
function getEnvVar(key: string): string {
const value = process.env[key]
if (!value) {
throw new Error(`Missing required environment variable: ${key}`)
}
return value
}
export const config = {
databaseUrl: getEnvVar('DATABASE_URL'),
apiSecret: getEnvVar('API_SECRET'),
} as const
Importez ce module de configuration au point d’entrée de votre application. Si une variable manque, vous le saurez immédiatement plutôt que de le découvrir en pleine requête.
Pour une validation plus robuste, des bibliothèques comme Zod vous permettent de définir des schémas qui valident les types, formats et contraintes :
import { z } from 'zod'
const envSchema = z.object({
DATABASE_URL: z.string().url(),
PORT: z.string().transform(Number).pipe(z.number().min(1)),
})
export const env = envSchema.parse(process.env)
Cela échoue rapidement avec des messages d’erreur clairs si DATABASE_URL n’est pas une URL valide ou si PORT n’est pas un nombre.
Garder vos variables sécurisées
Rappelez-vous les règles de préfixe. Dans les projets Vite, seules les variables préfixées VITE_ atteignent le navigateur. Tout le reste n’est disponible que pour le processus de compilation (côté serveur) et n’est pas livré au navigateur. Ne mettez jamais de secrets dans des variables préfixées—elles seront visibles dans votre bundle de production.
Pour les secrets côté serveur, comptez sur la configuration d’environnement de votre plateforme d’hébergement plutôt que sur les fichiers .env en production. Ajoutez .env à votre .gitignore immédiatement.
Conclusion
Les variables d’environnement type-safe en TypeScript nécessitent deux couches : la fusion de déclarations pour l’autocomplétion au moment de la compilation et la validation à l’exécution pour la sécurité en production. Utilisez ImportMetaEnv pour les projets Vite, NodeJS.ProcessEnv pour les contextes Node, et validez toujours les variables requises au démarrage. Votre futur vous—en train de déboguer un incident de production à 3 heures du matin—vous remerciera.
FAQ
Oui, mais gardez les déclarations séparées. Créez un fichier env.d.ts avec ImportMetaEnv pour vos packages frontend Vite et un globals.d.ts avec l'augmentation NodeJS.ProcessEnv pour les packages backend. Le tsconfig.json de chaque package ne devrait inclure que son fichier de déclaration pertinent pour éviter les conflits de types.
Votre tsconfig.json n'inclut probablement pas le fichier de déclaration. Vérifiez que votre tableau include couvre l'emplacement du fichier, ou ajoutez le chemin du fichier explicitement. Vérifiez également que vous ne masquez pas accidentellement l'interface dans un autre fichier de déclaration. Redémarrez votre serveur TypeScript après avoir effectué des modifications.
Pour les applications frontend, la validation au moment de la compilation est plus utile car les variables sont intégrées pendant le processus de build. Ajoutez un script prebuild qui vérifie que les variables VITE_ requises existent avant que Vite ne s'exécute. La validation à l'exécution dans le navigateur ne peut de toute façon pas récupérer des variables manquantes.
Marquez les variables optionnelles avec un point d'interrogation dans votre déclaration d'interface, comme OPTIONAL_VAR?: string. Pour la validation, utilisez la méthode optional() de Zod ou fournissez des valeurs par défaut avec default(). Votre objet de configuration devrait refléter quelles variables sont vraiment requises par rapport à celles qui sont souhaitables.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.