Cuando un proyecto crece y el equipo se amplía, los errores de escritura en las variables de entorno se convierten en una fuente silenciosa de bugs en producción. Un simple API_HEI en lugar de API_KEY puede devolver un undefined, impedir la conexión a una base de datos y consumir horas de depuración sin que nadie entienda qué salió mal. Afortunadamente, TypeScript y NestJS ofrecen herramientas para blindar la configuración con tipado seguro y eliminar ese riesgo desde el momento de compilación.
¿Por qué los errores de typo en variables de entorno son tan peligrosos?
Cuando se accede a una variable de entorno mediante un string directo —por ejemplo process.env.API_HEI— el compilador no emite ninguna advertencia [0:20]. El valor simplemente será undefined o null, y el error solo se manifestará en tiempo de ejecución, a veces ya en producción.
- No existe autocompletado que avise del nombre correcto.
- Sin pruebas unitarias, el fallo pasa desapercibido fácilmente.
- En equipos grandes, cada desarrollador puede digitar la variable de forma distinta.
La solución es dejar de confiar en strings sueltos y crear una capa de configuración tipada que TypeScript pueda validar.
¿Cómo crear un archivo de configuración tipado en NestJS?
El primer paso es generar un archivo llamado config.ts junto al directorio de environments [1:30]. Dentro de él se importa registerAs desde @nestjs/config y se exporta una función con nombre:
typescript
import { registerAs } from '@nestjs/config';
export default registerAs('config', () => ({
apiKey: process.env.API_KEY,
database: {
name: process.env.DATABASE_NAME,
port: process.env.DATABASE_PORT,
},
}));
El concepto de registerAs permite registrar un espacio de nombres (namespace) para la configuración. Esto aporta dos ventajas claras:
- Agrupación de variables: a diferencia de un archivo
.env, donde todo es una lista plana, aquí se pueden anidar propiedades relacionadas dentro de un objeto como database [2:25].
- Tipado seguro: TypeScript conoce la forma exacta del objeto que retorna la función, así que cualquier error de escritura se detecta antes de ejecutar.
¿Cómo se inyecta la configuración tipada en un servicio?
En el servicio donde se necesitan las variables, se reemplaza el uso tradicional de ConfigService por la inyección directa del namespace tipado [4:00]:
typescript
import { Inject, Injectable } from '@nestjs/common';
import config from './config';
import { ConfigType } from '@nestjs/config';
@Injectable()
export class AppService {
constructor(
@Inject(config.KEY)
private configService: ConfigType<typeof config>,
) {}
}
El tipo ConfigType extrae la forma del objeto registrado con registerAs. De este modo, al escribir this.configService.apiKey o this.configService.database.name, el editor muestra autocompletado y marca cualquier propiedad inexistente como error de compilación [4:55].
¿Qué configuración se necesita en el módulo principal?
Para que la inyección de dependencias funcione, es necesario cargar el archivo de configuración en el AppModule [5:50]:
typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import config from './config';
@Module({
imports: [
ConfigModule.forRoot({
load: [config],
}),
],
})
export class AppModule {}
La propiedad load recibe un arreglo porque pueden existir múltiples archivos de configuración. NestJS los lee, resuelve las variables desde el .env correspondiente y las pone disponibles con tipado completo.
¿Cuándo conviene aplicar tipado seguro a la configuración?
Si el proyecto es pequeño y el equipo tiene total control, usar configService.get('API_KEY') con un string puede ser suficiente [6:45]. Sin embargo, en software de gran escala o equipos numerosos, tipar la configuración se considera una buena práctica porque:
- Se detectan errores en tiempo de compilación, no en producción.
- El autocompletado acelera el desarrollo y reduce la fricción.
- La agrupación de variables mejora la legibilidad del código.
La decisión final depende del contexto del equipo, pero blindar las variables de entorno con TypeScript es una inversión que se paga sola cada vez que se evita un bug silencioso. ¿Ya estás tipando tu configuración o prefieres el enfoque clásico? Comparte tu experiencia.