Introdução: "Cannot find module" — uma dor familiar?
\n\nVocê está programando em TypeScript, adiciona um belo ícone no formato SVG ao projeto e tenta importá-lo da maneira padrão:
\n\nimport Logo from './assets/logo.svg';\n\nE então o TypeScript exibe um erro vermelho:
\n\nCannot find module './assets/logo.svg' or its corresponding type declarations.\n\nFamiliar? Se você já enfrentou esse problema pelo menos uma vez — não está sozinho. A pergunta "Unable to import svg files in typescript" no Stack Overflow acumulou milhares de visualizações e dezenas de respostas. O problema é que o TypeScript, por padrão, não sabe como processar arquivos não-código (SVG, PNG, CSS).
\n\nNeste artigo, vamos abordar uma explicação completa com código: por que o erro ocorre e como corrigi-lo de uma vez por todas. Você aprenderá sobre declaration files, configuração do Webpack e Vite, além de como tipar corretamente SVG em projetos React.
\n\nPor que o TypeScript não vê SVG?
\n\nTypeScript é uma linguagem estritamente tipada. Ela verifica os tipos em tempo de compilação. Quando você escreve import Logo from './logo.svg', o TypeScript espera que o módulo ./logo.svg exporte algo com um tipo conhecido. Mas SVG não é um arquivo TypeScript, é XML. O TypeScript não possui uma descrição embutida para módulos SVG.
Daí o erro: o compilador não consegue encontrar type declarations (declarações de tipos) para este arquivo.
\n\nExistem três maneiras principais de resolver o problema:
\n\n- \n
- Maneira 1: Criar um arquivo de declaração global (
.d.ts) \n - Maneira 2: Usar Webpack/Vite com os loaders corretos \n
- Maneira 3: Importar SVG via
urlouraw(para casos específicos) \n
Vamos abordar cada maneira com exemplos de código.
\n\nManeira 1: Arquivo de declaração global (o mais popular)
\n\nEsta é a solução do Stack Overflow que funciona em 90% dos casos. Você cria um arquivo com a extensão .d.ts (por exemplo, src/declarations.d.ts ou src/svg.d.ts) e declara o módulo para SVG.
Aqui está o código mínimo:
\n\n// src/declarations.d.ts\ndeclare module '*.svg' {\n const content: string;\n export default content;\n}\n\nO que está acontecendo aqui? Estamos dizendo ao TypeScript: "Qualquer arquivo com a extensão .svg é um módulo que exporta por padrão uma string (caminho do arquivo ou conteúdo)".
Se você estiver usando React e quiser importar SVG como um componente React (via @svgr/webpack ou vite-plugin-svgr), a declaração será diferente:
// src/declarations.d.ts\ndeclare module '*.svg' {\n import React from 'react';\n const SVGComponent: React.FC<React.SVGProps<SVGSVGElement>>;\n export default SVGComponent;\n}\n\nImportante: Certifique-se de que o arquivo .d.ts está incluído no seu tsconfig.json. Normalmente, basta que ele esteja dentro de src/, mas se não estiver, adicione o caminho no campo include:
// tsconfig.json\n{\n "compilerOptions": {\n // ... outras configurações\n },\n "include": ["src/**/*"]\n}\n\nDepois disso, o erro "Cannot find module" desaparecerá e você poderá importar SVG normalmente.
\n\nManeira 2: Configuração do Webpack ou Vite
\n\nA declaração global é apenas metade do trabalho. Para que a importação funcione de fato em tempo de execução (no navegador), é necessário configurar o bundler.
\n\nPara Webpack
\n\nInstale o file-loader ou url-loader:
npm install --save-dev file-loader\n\nAdicione a regra no webpack.config.js:
// webpack.config.