No se pueden importar archivos svg en mecanografiado

109

En typescript(*.tsx)archivos no puedo importar archivos svg con esta declaración:

import logo from './logo.svg';

Transpiler dice: [ts] cannot find module './logo.svg'. Mi archivo svg es solo <svg>...</svg>.

Pero en el .jsarchivo puedo importarlo sin problemas con exactamente la misma declaración de importación. Supongo que tiene algo que ver con el tipo de archivo svg que debe configurarse de alguna manera para ts transpiler.

¿Podría compartir cómo hacer que esto funcione en archivos ts?

Muchacho enojado
fuente
2
Los archivos svg no son javascript y no se pueden usar como los módulos javascript. Debería cargar esos archivos usando una solicitud http en su lugar.
toskv
1
¿Estás usando Webpack? Eso es lo único que he visto entender tal importafirmación. Quizás Webpack es lo que permite esto en su JavaScript, pero no está haciendo la misma magia en los archivos TypeScript. (No creo que TypeScript sepa qué hacer aquí.)
user94559
1
Si está utilizando Webpack, probablemente necesitará compartir su configuración de Webpack para obtener más ayuda.
user94559
2
Si lee un poco más sobre esto, probablemente pueda hacer const logo = require("./logo.svg");o simplemente ignorar el error. (Creo que TS aún debería generar el código correcto).
user94559
¡muchas gracias! ¡Requiere funciona bien! En mi caso tiene que ser const logo = require("./logo.svg") as string;
AngryBoy

Respuestas:

185

Si usa webpack, puede hacer esto creando un archivo de tipos personalizados.

Cree un archivo llamado custom.d.ts con el siguiente contenido:

declare module "*.svg" {
  const content: any;
  export default content;
}

Agregue el custom.d.tsa tsconfig.jsoncomo se muestra a continuación

"include": ["src/components", "src/custom.d.ts"]

Fuente: https://webpack.js.org/guides/typescript/#importing-other-assets

Graham
fuente
36
Probablemente, necesitaría agregarlo a la includesección en tsconfig.json .
Frederik Krautwald
12
¡Gracias! Sabía que debía incluirse en alguna parte, pero no puedo imaginarme dónde. Incluso pensé que estaba en tsconfig.json pero no sabía cómo hacerlo. Gracias por tu comentario. Hice una búsqueda y encontré:"files": [ "custom.d.ts" ]
Shil Nevado
5
Puede obtener una verificación de tipo para el componente JSX escribiendo el contenido:const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
RedMatt
¿Es posible que el custom.d.tsarchivo funcione globalmente para que el SVG pueda estar en un directorio diferente al del custom.d.tsarchivo? Recibo un error "no se puede encontrar el módulo" a menos que esté en el mismo directorio.
Nic Scozzaro
1
Esto no importa el contenido del archivo en Angular, importa el nombre del archivo como una cadena. Necesito el contenido. ¿Cómo obtenemos el contenido del archivo?
Routhinator
37

Gracias smarx por señalar el uso require(). Entonces en mi caso debería ser:

const logo = require("./logo.svg") as string;

que funciona bien en archivos * .tsx

Muchacho enojado
fuente
5
logopodría ser mejor nombrado logoPath, porque en eso se convierte.
DharmaTurtle
2
@DharmaTurtle Creo que se puede debatir. Además, se llama logoen la pregunta, por lo que es una mejor respuesta a esta pregunta específica tal como está.
ArneHugo
17

Agregue un custom.d.tsarchivo (lo creé en la ruta raíz de mi directorio src) con el tipo correcto (gracias a RedMatt ):

declare module '*.svg' {
  const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
  export default content;
}

Instale svg-react-loader o algún otro , luego:

  • Úselo como el cargador principal de svg
  • O si está migrando una base de código y no desea tocar la parte de trabajo (JS), especifique el cargador en la importación:
import MySVG from '-!svg-react-loader!src/assets/images/name.svg'

Luego utilícelo como una etiqueta JSX:

function f() { 
  return (<MySVG />); 
}
Allenaz
fuente
4

La solución que encontré: en el proyecto ReactJS, en el archivo react-app-env.d.ts simplemente elimina el espacio en el comentario, como por ejemplo:

antes de

// / <reference types="react-scripts" />

Después

/// <reference types="react-scripts" />

Espero poder ayudarte

jilvanx
fuente
Para las personas que usan create-react-app y configuran eslint, esto puede resolver el problema
Daniel Chin
2

Tuve el mismo problema al probar un tutorial de REACT + mecanografiado.
Lo que funcionó para mí fue la siguiente declaración de importación.

import * as logo from 'logo.svg'

Aquí están mis dependencias en package.json.

  "dependencies": {
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-scripts-ts": "3.1.0"
  },

Espero que ayude a alguien.

Kiran Mohan
fuente
1

Para usar n activos en código con TypeScript , debemos diferir el tipo para estas importaciones . Esto requiere un archivo custom.d.ts que significa definiciones personalizadas para TypeScript en nuestro proyecto.

Configuremos una declaración para archivos .svg:

custom.d.ts

declare module "*.svg" {
  const content: any;
  export default content;
}

Aquí declaramos un nuevo módulo para SVG especificando cualquier importación que termine en .svg y definiendo el contenido del módulo como cualquiera.

Mehadi Hassan
fuente
0

Hay una forma alternativa de hacer esto que hemos implementado: haga sus componentes SVG. Hice esto porque me molestaba que estuviera usando requiredeclaraciones commonJS junto con mi imports.

endymion1818
fuente
0
    // eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

si está utilizando el puglin slint, puede ser que haya deshabilitado pensando que era un comentario, pero no para leer el svg, necesita este módulo de script de tipo, simplemente deshabilite la línea y sea feliz

Breno Melo
fuente