Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як імпортувати SVG, CSS чи зображення в TypeScript і чому declare module для них інколи не працює?

Збирачі (Vite, webpack) дозволяють імпортувати не лише код: import logo from './logo.svg'. TypeScript про такі файли нічого не знає і повідомляє «Cannot find module './logo.svg'».

Рішення - ambient-оголошення модуля з шаблоном:

// src/assets.d.ts
declare module '*.svg' {
  const src: string;
  export default src;
}

declare module '*.module.css' {
  const classes: Readonly<Record<string, string>>;
  export default classes;
}

Тепер будь-який імпорт, що закінчується на .svg, має тип рядка (URL файлу).

Vite вже має такі оголошення - досить підключити їх: "types": ["vite/client"] у tsconfig або /// <reference types="vite/client" /> у файлі vite-env.d.ts. Там описано і ?url, ?raw, ?inline, і import.meta.env.

Чому declare module '*.svg' інколи «не працює». Найчастіша причина - файл з оголошенням є модулем: у ньому є import чи export на верхньому рівні.

// assets.d.ts - НЕ спрацює
import type { FC } from 'react';
declare module '*.svg' {
  const Component: FC;
  export default Component;
}

У файлі-модулі declare module 'назва' - це доповнення (augmentation) існуючого модуля, а доповнити шаблон, якого немає, неможливо. Ambient-оголошення нових модулів мають бути у скрипті - .d.ts без імпортів на верхньому рівні. Якщо тип потрібен з іншого пакета - імпорт всередині блоку:

declare module '*.svg?react' {
  import type { FC, SVGProps } from 'react';
  const Component: FC<SVGProps<SVGSVGElement>>;
  export default Component;
}

Інші причини:

  • файл з оголошеннями не входить у include чи files у tsconfig;
  • шаблон не збігається ('*.svg' проти імпорту з ?react на кінці).

Обережно з «заглушками»: declare module 'some-lib'; без тіла робить усі імпорти з пакета типу any - це прибирає помилку, але й будь-яку перевірку. Для бібліотек краще знайти чи написати справжні типи.

Докладніше в документації: Довідник модулів: ambient-модулі

Схожі питання