Cómo importar JSON en TypeScript y no volverse loco
\n\nSi alguna vez has intentado hacer import data from './config.json' en TypeScript, conoces esa sensación: el compilador se pone rojo, se queja y lanza el error Cannot find module. ¿Un dolor familiar? ¡Y tanto! La pregunta sobre la importación de JSON en TypeScript es una de las más populares en Stack Overflow. Y no es de extrañar: JSON se usa en todas partes: configuraciones, localización, datos mock, listas estáticas. Pero TypeScript, por defecto, no sabe trabajar con archivos JSON.
En este tutorial, analizaremos todas las formas de importar JSON en TypeScript, desde simplemente activar una bandera en tsconfig hasta la tipificación avanzada. Aprenderás cómo hacer que TypeScript se lleve bien con JSON y nunca más verás ese error rojo. ¡Vamos allá!
\n\n¿Por qué TypeScript no ve el JSON?
\nAntes de sumergirnos en el código, entendamos la causa. TypeScript es una extensión de JavaScript que añade tipificación estática. Por defecto, el compilador de TypeScript espera que todos los módulos importados sean archivos .ts o .js. JSON no es un módulo, es un formato de datos. TypeScript simplemente no sabe cómo interpretarlo.
\nLa solución se encuentra en dos planos:
\n- \n
- Configuración del compilador — activar la compatibilidad con JSON mediante la bandera
resolveJsonModule. \n - Declaración del módulo — describir manualmente el tipo para archivos JSON, si la bandera no es adecuada. \n
Método 1: Activar resolveJsonModule (el camino correcto)
\nLa forma más sencilla y recomendada es añadir la opción resolveJsonModule en tsconfig.json. Esta bandera le dice a TypeScript: "Oye, amigo, vamos a importar JSON como módulos normales".
// tsconfig.json\n{\n "compilerOptions": {\n "resolveJsonModule": true,\n "esModuleInterop": true\n }\n}\nDespués de esto, puedes escribir tranquilamente:
\n// config.ts\nimport config from './config.json';\n\nconsole.log(config.apiUrl); // ¡funciona!\nconsole.log(config.port); // ¡funciona!\n¿Qué ocurre aquí? TypeScript crea automáticamente tipos para el JSON importado. Si tu JSON tiene un campo apiUrl: string y port: number, TypeScript inferirá sus tipos y verificará su uso. Genial, ¿verdad?
Pero hay un detalle: resolveJsonModule también requiere activar esModuleInterop o allowSyntheticDefaultImports para que la importación por defecto funcione correctamente. Sin esto, obtendrás un error al intentar importar.
Método 2: Importación con exportaciones nombradas
\nA veces no necesitas todo el JSON, sino solo ciertos campos. TypeScript también admite esto:
\nimport { apiUrl, port } from './config.json';\n\nconsole.log(apiUrl); // cadena\nconsole.log(port); // número\nEsto es posible gracias al llamado "tree-shaking" en los bundlers (Webpack, Vite), pero a nivel de TypeScript es simplemente desestructuración de objetos. Sin embargo, recuerda: si usas resolveJsonModule, TypeScript crea automáticamente tipos para todos los campos, por lo que puedes importar tanto el objeto completo como sus partes.
Método 3: require en lugar de import (para proyectos antiguos)
\nSi trabajas en un proyecto donde resolveJsonModule no se puede activar por alguna razón (por ejemplo, conflicto con otras configuraciones), puedes usar el clásico require:
const config = require('./config.json');\n\nconsole.log(config.apiUrl); // funciona, pero sin tipos\nEl problema de este enfoque es obvio: pierdes la tipificación. TypeScript no sabe qué hay dentro de config y lo considerará de tipo any. Esto abre la puerta a errores. Si usas require, al menos añade una declaración de tipo:
interface Config {\n apiUrl: string;\n port: number;