¿Cómo importar un archivo JSON a un archivo TypeScript?

86

Estoy construyendo una aplicación de mapas usando Angular Maps y quiero importar un archivo JSON como una lista de marcadores que definen ubicaciones. Espero usar este archivo JSON como matriz de marcador [] dentro de app.component.ts. En lugar de definir una matriz de marcadores codificada dentro del archivo TypeScript.

¿Cuál es el mejor proceso para importar este archivo JSON para usar en mi proyecto? ¡Cualquier dirección muy apreciada!

aonepathan
fuente
puede ver mi respuesta, ya que es aplicable a Angular 7+
Yulian

Respuestas:

115

El one-liner de Aonepathan funcionó para mí hasta una reciente actualización mecanografiada.

He encontrado de Jecelyn Yeen puesto que sugiere la publicación de este fragmento en el archivo de definición de TS

agregue el archivo typings.d.tsa la carpeta raíz del proyecto con el contenido a continuación

declare module "*.json" {
    const value: any;
    export default value;
}

y luego importe sus datos así:

import * as data from './example.json';

actualización de julio de 2019:

TypeScript 2.9 ( docs ) presentó una solución mejor y más inteligente. Pasos:

  1. Agregue resolveJsonModulesoporte con esta línea en su tsconfig.jsonarchivo:
"compilerOptions": {
    ...
    "resolveJsonModule": true
  }

la declaración de importación ahora puede asumir una exportación predeterminada:

import data from './example.json';

e intellisense ahora verificará el archivo json para ver si puede usar los métodos Array, etc. muy genial.

Ryanrain
fuente
3
Esto también funcionó para mí, ¡súper hábil! NOTA: Necesita reiniciar su servidor de desarrollo para que esto se compile correctamente.
Scott Byers
13
Estoy recibiendoCannot find module '*.json'. Consider using '--resolveJsonModule' to import module with '.json' extensionts(2732)
Jeremy Thille
4
También necesitaba agregar "esModuleInterop": true,como se especifica en los documentos mecanografiados, sin embargo, también dicen usar commonjscomo en modulelugar de esnext. Esto parece funcionar con ambos. ¿Hay alguna razón para cambiar a commonjs (como se menciona en los documentos) como oponerse a seguir con el valor predeterminado de esnext?
timhc22
1
lo mismo que los comentarios anteriores que necesitaba "esModuleInterop":true. También el código VS todavía me muestra un error ... pero todo funciona bien
mikey
6
He tenido que añadir "allowSyntheticDefaultImports": trueen el compilerOptions, así como con un proyecto fresco angular 9.1.11.
yohosuff
28

Como se indica en esta publicación de Reddit , después de Angular 7, puede simplificar las cosas a estos 2 pasos:

  1. Agregue esas tres líneas a compilerOptionssu tsconfig.jsonarchivo:
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
  1. Importe sus datos json:
import myData from '../assets/data/my-data.json';

Y eso es. Ahora puede utilizarlo myDataen sus componentes / servicios.

Yulian
fuente
Lo que es esModuleInteroppara?
giovannipds
@giovannipds es para las importaciones json predeterminadas
Vasia Zaretskyi hace
25

Aquí hay una respuesta completa para Angular 6+ basada en la respuesta de @ryanrain:

Desde angular-cli doc , json se puede considerar como activos y se puede acceder a él desde la importación estándar sin el uso de la solicitud ajax.

Supongamos que agrega sus archivos json en el directorio "your-json-dir":

  1. agregue "su-json-dir" en el archivo angular.json (:

    "assets": [ "src/assets", "src/your-json-dir" ]

  2. cree o edite el archivo typings.d.ts (en la raíz de su proyecto) y agregue el siguiente contenido:

    declare module "*.json" { const value: any; export default value; }

    Esto permitirá la importación de módulos ".json" sin errores de mecanografía.

  3. en su controlador / servicio / cualquier otro archivo, simplemente importe el archivo utilizando esta ruta relativa:

    import * as myJson from 'your-json-dir/your-json-file.json';

Benjamin Caure
fuente
3
¿Qué pasa si no tengo un archivo typings.d.ts?
Kristopher Windsor
2
luego debe crear uno en la raíz de su proyecto con solo el contenido del paso 2
Benjamin Caure
2
Nota importante: agregue el archivo de escritura personalizado a typeRoots en tsconfig.json "typeRoots": ["node_modules / @ types", "src / typings.d.ts"],
Japo Domingo
22

Gracias por los chicos de entrada, pude encontrar la solución, agregué y definí el json en la parte superior del archivo app.component.ts:

var json = require('./[yourFileNameHere].json');

Esto finalmente produjo los marcadores y es una simple línea de código.

aonepathan
fuente
6
Me error TS2304: Cannot find name 'require'.resolví agregando declare var require: any;, como se explica en los comentarios de la respuesta aceptada para la pregunta stackoverflow.com/questions/43104114/… .
Ben
4
@Ben, debe agregar el tipo de nodo a su tsconfig. es decir, "compilerOptions": { ... "types": ["node"] },aquí está la respuesta relacionada para aquellos que la requieren: stackoverflow.com/a/35961176/1754995
Kody
Hola @aonepathan, espero que puedas ayudarme: tengo una biblioteca que requiere leer un archivo json. var json = require('./[yourFileNameHere]');sin la extensión. En el momento de la compilación, tengo un error: Module not found: Error: Can't resolve [yourFileNameHere] in [file name]¿tiene alguna idea para evitar este problema?
Neo1975
16

Primera solución : simplemente cambie la extensión de su archivo .json a .ts y agregue export defaultal principio del archivo, así:

export default {
   property: value;
}

Luego, simplemente puede importar el archivo sin la necesidad de agregar mecanografía, así:

import data from 'data';

La segunda solución obtiene el json a través de HttpClient.

Inyecte HttpClient en su componente, así:

export class AppComponent  {
  constructor(public http: HttpClient) {}
}

y luego usa este código:

this.http.get('/your.json').subscribe(data => {
  this.results = data;
});

https://angular.io/guide/http

Esta solución tiene una clara ventaja sobre otras soluciones proporcionadas aquí: no requiere que reconstruya la aplicación completa si su json cambia (se carga dinámicamente desde un archivo separado, por lo que puede modificar solo ese archivo).

vicbyte
fuente
1
La primera solución es buena si sus datos son estáticos y no cambiarán durante mucho tiempo; le ahorrará solicitudes http innecesarias, pero si estos datos cambian constantemente, utilice la segunda solución enviada por el servidor o incluso considere agregarla a una base de datos si el conjunto de datos es enorme
OzzyTheGiant
10

Había leído algunas de las respuestas y no parecían funcionar para mí. Estoy usando TypeScript 2.9.2, Angular 6 e intento importar JSON en una prueba unitaria de Jasmine. Esto es lo que me sirvió.

Añadir:

"resolveJsonModule": true,

A tsconfig.json

Importar como:

import * as nameOfJson from 'path/to/file.json';

Deténgase ng test, comience de nuevo.

Referencia: https://blogs.msdn.microsoft.com/typescript/2018/05/31/announcing-typescript-2-9/#json-imports

Ian Jamieson
fuente
1
Esta fue la mejor solución para mí. No se necesita un archivo de mecanografía y TS puede resolver los nombres de las propiedades por usted.
Steve Hobbs
7

Para Angular 7+,

1) agregue un archivo "typings.d.ts" a la carpeta raíz del proyecto (por ejemplo, src / typings.d.ts):

declare module "*.json" {
    const value: any;
    export default value;
}

2) importar y acceder a datos JSON:

import * as data from 'path/to/jsonData/example.json';
...
export class ExampleComponent {
    constructor() {
        console.log(data.default);
    }

}

o:

import data from 'path/to/jsonData/example.json';
...
export class ExampleComponent {
    constructor() {
        console.log(data);
    }

}
Stevemaster92
fuente
data.default me ​​estaba colgando. ¡Gracias por el ejemplo completo!
kevin_fitz
Tenga cuidado con la ruta a su archivo json porque es relevante para el archivo que importa el archivo, por ejemplo, si tiene un servicio en la src/app/services/carpeta y su json está en la src/assets/data/carpeta, debe especificarlo como../../assets/data/your.json
Adam Boczek
Funciona perfectamente, pero ¿por qué se necesita el archivo typings.d.ts?
robert
5

En angular7, simplemente usé

let routesObject = require('./routes.json');

Mi archivo route.json se ve así

{

    "routeEmployeeList":    "employee-list",
    "routeEmployeeDetail":      "employee/:id"
}

Accede a elementos json usando

routesObject.routeEmployeeList
Kodjo Tchioffo
fuente
¡Eso es! ;-) ¡Todas las otras opciones son tan hacky! Si tiene TSLint, arrojará un reuqireerror, simplemente agregue declare var require: any;encima del componente de clase.
Pedro Ferreira
5

A partir de Typecript 2.9 , simplemente se puede agregar:

"compilerOptions": {
    "resolveJsonModule": true
}

al tsconfig.json. A partir de entonces, es fácil usar un archivo json ( y también habrá una buena inferencia de tipo en VSCode):

data.json:

{
    "cases": [
        {
            "foo": "bar"
        }
    ]
}

En su archivo de TypeScript:

import { cases } from './data.json';

Nigel Gilbert
fuente
2
let fs = require('fs');
let markers;
fs.readFile('./markers.json', handleJSONFile);

var handleJSONFile = function (err, data) {
   if (err) {
      throw err;
   }
   markers= JSON.parse(data);
 }
Fateh Mohamed
fuente
2

Angular 10

Ahora debería editar el tsconfig.app.json(observe la "aplicación" archivo en el nombre) en su lugar.

Allí encontrará el compilerOptions, y simplemente agregue resolveJsonModule: true.

Entonces, por ejemplo, el archivo en un proyecto nuevo debería verse así:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [],
    "resolveJsonModule": true
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}
Absay
fuente