Ошибка импорта SVG файлов в TypeScript: Cannot find module или неверный тип
Причина проблемы
TypeScript по умолчанию не знает, что такое SVG-файлы. Он умеет импортировать только .ts, .tsx, .js, .jsx, .d.ts и другие стандартные расширения. Когда вы пишете import Logo from './logo.svg', компилятор ищет модуль с таким именем, но не находит его, потому что для .svg нет объявлений типов (type declarations).
Решение: создание декларации модуля (declaration file)
Вам нужно объявить TypeScript, что SVG-файлы — это валидные модули. Для этого создайте файл src/custom.d.ts (или src/declarations.d.ts) со следующим содержимым:
// src/custom.d.ts
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
Объяснение кода
- declare module '*.svg' — говорит TypeScript: "любой файл, который заканчивается на .svg, обрабатывай как модуль с этими экспортами".
- ReactComponent — это именованный экспорт, который используется в синтаксисе
import { ReactComponent as Logo } from './logo.svg'. Мы типизируем его как функциональный компонент React, принимающий стандартные SVG-пропсы. - export default src: string — это для случая, когда вы импортируете SVG как URL:
import logoSrc from './logo.svg'. Тип string подходит, потому что в результате вы получите строку с путём к файлу (например,/static/media/logo.abc123.svg).
Проверка и использование
После добавления этого файла перезапустите вашу IDE (или просто перезагрузите TypeScript сервер в VS Code через Ctrl+Shift+P → "TypeScript: Restart TS server"). Теперь оба варианта импорта будут работать без ошибок:
// Вариант 1: как React-компонент
import { ReactComponent as Logo } from './logo.svg';
<Logo width={50} height={50} />
// Вариант 2: как URL для src
import logoSrc from './logo.svg';
<img src={logoSrc} alt="Logo" />
Если вы используете Create React App (CRA)
В CRA с TypeScript шаблоном обычно уже есть файл react-app-env.d.ts. Если он есть — просто добавьте туда объявление модуля для SVG. Если нет — создайте. CRA сам обрабатывает SVG через Webpack (с помощью @svgr/webpack и file-loader), поэтому декларация типов — это единственное, что нужно добавить.
Дополнительные советы
- Убедитесь, что файл
custom.d.tsнаходится в папке, которая включена вincludeв вашемtsconfig.json(по умолчанию этоsrc). - Если вы используете Vite, Next.js или другой фреймворк — проверьте их документацию. Например, в Vite SVG импорт работает из коробки, но типы нужно объявлять отдельно.
- Не забудьте удалить
require('./logo.svg'), если он у вас остался — он не даёт корректной типизации.
После этих шагов ошибка Cannot find module исчезнет, и вы сможете использовать SVG как настоящие React-компоненты с полной поддержкой типов.
Альтернативный подход: использование библиотеки @types
Если вы не хотите вручную создавать декларации, можно установить пакет @types/webpack-env (если вы используете Webpack, как в CRA) или @types/node, которые иногда включают базовые типы для импорта файлов. Однако это не всегда решает проблему со SVG, так как типы для SVG-компонентов там отсутствуют.
Для проектов на Vite
В Vite SVG импорт работает иначе. Вам нужно установить плагин vite-plugin-svgr и добавить его в конфигурацию. После этого создайте файл src/vite-env.d.ts с таким содержимым:
/// <reference types="vite/client" />
declare module '*.svg' {
import React from 'react';
const SVGComponent: React.FC<React.SVGProps<SVGSVGElement>>;
export default SVGComponent;
}
Для Next.js
В Next.js 13+ SVG импорт без дополнительных настроек не работает. Рекомендуется использовать next-image для статических SVG или пакет @svgr/webpack с настройкой в next.config.js. Типы объявляются аналогично — через custom.d.ts.
Краткий итог
Самый универсальный и простой способ — создать файл декларации. Он работает в любом окружении (CRA, Vite, Next.js, Webpack, Rollup) и не требует установки дополнительных зависимостей. Второй вариант — использовать специфичные для сборщика плагины, но это усложняет конфигурацию.
Ответов пока нет.
Войдите чтобы оставить ответ