typescript cannot find module when import svg file
Asked Answered
L

4

16

It's web application created with Typescript, React and webpack. I want to use svg file through webpack. However, I got

    TS2307: Cannot find module '~/images/slide.svg'. 

Typescript files are put on /frontend/src/, and typescript files are build successfully.

Then, I tried some solutions on website. But I could not solve this problem. What I tried is described briefly as follows.

I added a file where defined types in 'typeRoots'. tsconfig.json

{
  "compilerOptions": {
    "outDir": "./app/assets/javascripts/bundles",
    "sourceMap": true,
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "moduleResolution": "node",
    "module": "es2015",
    "target": "es6",
    "jsx": "react",
    "removeComments": true,
    "baseUrl": ".",
    "paths": {
      "~/*": ["./frontend/src/*"]
    },
    "typeRoots": ["types", "node_modules/@types"]
  },
  "awesomeTypescriptLoaderOptions": {
    "useCache": true,
    "cacheDirectory": "tmp/build_caches/awesome-typescript-loader"
  },
  "include": [
    "./frontend/src/*"
  ],
  "exclude": [
    "node_modules",
    "bundles",
    "**/*.js"
  ]
}

types/images.d.ts

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

I use 'file-loader' on webpack to build svg fild.

Please help me!!

Luther answered 6/11, 2019 at 8:56 Comment(0)
C
12

I think it is because of your include section in the Typescript config. Try this:

"include": [
  "./frontend/src/**/*"
],

Otherwise you are only including typing files which are in src folder top level. And your svg typing file is in a sublevel so Typescript will not include it.

Cule answered 6/11, 2019 at 9:3 Comment(1)
File specification cannot end in a recursive directory wildcard (''): './src/*/'.Intercalation
P
19

If you are using Nextjs, you can create a new file additional.d.ts (same level as next-env.d.ts) and declare modules for image files. You should then include this file in your tsconfig.json.

additional.d.ts:

declare module "*.png";
declare module "*.jpg";
declare module "*.jpeg";
declare module "*.svg";
declare module "*.gif";

tsconfig.json:

{
  ...
  "include": ["next-env.d.ts", "additional.d.ts", "**/*.ts", "**/*.tsx"],
}
Portauprince answered 13/7, 2021 at 22:27 Comment(1)
this worked for me. including "*/.ts", "*/.tsx" after my "src/custom.d.ts"Derouen
F
18

The accepted answer caused odd behavior for me. For example, my build was not failing if I referenced an undefined variable.

What worked for me:

  1. Create custom.d.ts in project root:
declare module '*.svg' {
  import React = require('react');
  export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}
  1. Add custom.d.ts in tsconfig.json's include
"include": [
  ...,
  "custom.d.ts"
]
  1. Usage:
import { ReactComponent as MyIcon } from '../icon.svg'

...

function MyComponent() {
  return <MyIcon></MyIcon>
}
Fontenot answered 23/12, 2021 at 21:28 Comment(4)
This should be the accepted answer as the current one didn't worked for me.Disciple
@VaibhavGoyal I couldn't agree more!Configuration
Better to put in /{project_root}/types/svg.module.d.tsQuass
duncanleung.com/typescript-module-declearation-svg-img-assets This seems to have some good info tooQuass
C
12

I think it is because of your include section in the Typescript config. Try this:

"include": [
  "./frontend/src/**/*"
],

Otherwise you are only including typing files which are in src folder top level. And your svg typing file is in a sublevel so Typescript will not include it.

Cule answered 6/11, 2019 at 9:3 Comment(1)
File specification cannot end in a recursive directory wildcard (''): './src/*/'.Intercalation
E
3

I'd be better included like this:

  "include": ["**/*.ts", "**/*.tsx", "images.d.ts"],
Eckhart answered 19/12, 2020 at 10:28 Comment(1)
Why it would be better?Catie

© 2022 - 2024 — McMap. All rights reserved.