258

I am trying to import images to use inside a React component with TypeScript. The bundler I'm using is Parcel (not Webpack).

I have created a .d.ts file inside the project with the image file extension, and included it inside tsconfig.json. However, when I try to import an image, TS yells at me about Cannot find module.

My project structure:

+ src
  + assets
    - image.jpg
  + components
    - Box.tsx
    - App.tsx
  - index.d.ts
  - index.html
  - index.tsx
- tsconfig.json
- tslint.json

I tried to import the image in App.tsx like this. VS Code underlined '../assets/image.jpg' and said Cannot find module '../assets/image.jpg'.

import * as React from 'react';
import * as img from '../assets/image.jpg';

const Box = props => {
  // do things...
}

export default Box;

The discussions I found online point to the need of defining a .d.ts file myself, so I created that index.d.ts file with this line.

declare module '*.jpg';

Then added "include": ["./src/index.d.ts"] inside tsconfig.json, after "compilerOptions" : {...}.

What did I miss? How can I fix the error TS is throwing?

3

24 Answers 24

311

Create an index.d.ts file in the folder src, and add this line:

declare module '*.jpg';
Sign up to request clarification or add additional context in comments.

6 Comments

Works but can you please enlighten me on why and how this works? Does this have to do something with typescript, or is it vscode? Is it like ignoring the error in all like linting issues? Please clarify. Thanks.
@Rishav I think it's shorthand declaration specific typescriptlang.org/docs/handbook/modules.html All imports from a shorthand module will have the any type.
what is so strange is, if I close the index.d.ts file in vs code. then the error returns. only when the file is open does it work. Does anyone know why?
@loekTheDreamer I experience similar thing, error missing if I put reference directly in the file i.e put /// <reference path="../../index.d.ts" />
This didn't initially work for me. In my tsconfig file, include was set to "./src*" by default, which doesn't work. Changing it to "./src/**/*" and then adding the .d.ts file fixed it.
|
173

If you literally wrote "include": ["./src/index.d.ts"] in tsconfig.json and you don't have a "files" setting, that means the project defined by tsconfig.json includes only the single file ./src/index.d.ts. When you open any other file in VS Code, VS Code uses a separate language service instance that doesn't use your tsconfig.json. Adjust your "include" setting to match all the .ts and .tsx files in your project, or just delete it and rely on the default behavior of including all files under the directory containing tsconfig.json.

Round 2

TypeScript is ignoring index.d.ts because it assumes that index.d.ts is generated from index.tsx and index.tsx is more likely to be up to date. Name your index.d.ts file something else, e.g., declaration.d.ts.

6 Comments

I indeed literally wrote "include": ["./src/index.d.ts"] 😅. Now I have removed that line and restarted VS Code, but the problem remains (Cannot find module '../assets/image.jpg'). Can the problem be caused by the bundler? But if VS Code uses a separate language service, I think it doesn't matter which bundler is being used.
Never mind, I think I found the problem. See the updated answer.
Wow this is magic, thank you so much!! I spent almost the whole morning trying to figure out why it's not working :)))
Your Round 2 is the gift that keeps on giving. You just cleared up my issue with index.d.ts and SVGs, so thanks!
For your round 2, lunch is on me if we ever meet. Thank you so much!
|
123

Create module/type

# src/types/images.d.ts
declare module '*.jpg';
declare module '*.jpeg';

Change tsconfig.json

{
    "compilerOptions": {
        "typeRoots" : ["node_modules/@types", "src/types"]
    }
}

2 Comments

Hi I would like to dig a little because i have created types/images.d.ts and this typeRoots option did not help, however this same declaration - "src/types" in include worked, now my include looks like so "include": ["src/*", "src/types"], its a bit like duplicating paths as src/* should cover the second use case as well, but it does not. Why include worked and typeRoots did not since "'typeRoots' specifies root folders in which the transpiler should look for type definitions"
I did not need to modify typeRoots, simply dumping the d.ts file in the project worked.
56

There can be many solutions to this problem

Solution #1:
Use require to include image

<img src={require('../../assets/logo.png')} alt="" />

Solution #2:

Instead of importing images as import logo from "../../assets/logo.png"

Import as const logo = require("../../assets/logo.png");

then use it like

<img src={logo} alt="" />

Solution #3:
There is a react-app-env.d.ts file in your src folder. If you don't see it, create a new file in the src folder named react-app-env.d.ts.

Now in your react-app-env.d.ts, add this code.

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

Solution #4:
Create declaration.d.ts in your src folder.
Then add following text in it.

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

Now you have to make your tsconfig.json look like this:

{
  "compilerOptions": {},
  "include": [
    "src",
    "src/declaration.d.ts",
  ]
}

enter image description here


Solution #5:

Create a types folder in your src folder and add images.d.ts in this folder. Add below text in it.

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

Now configure tsconfig.json like this:

{
  "compilerOptions": {
    "typeRoots": [
      "node_modules/@types",
      "src/types"
    ],
}

enter image description here


3 Comments

const logo = require("../../assets/logo.png") gives the same error as import logo from "../../assets/logo.png". Please test what you write before you post it.
peter-schorn It worked for me that's I posted it here, and you can clearly see that I got points for it, means it helped others, If it does not work for try another solution, Simple :)
I used Solution #4, and it works fine in my react-native project. Thanks
32

For "react": "^18.2.0" with Typescript do the following:

  1. Create a file called: declaration.d.ts in your src/ dir.
  2. Add this lines of code:

declare module "*.jpg"
declare module "*.png"

That's it the error should be gone.

Good luck!

6 Comments

Can you explain in detail what this does?
Okay, what it does is It tells the typescript processor that any file with this extension is considered a module an can be important from anywhere in your project. Initially typescript processor will yell at you if it doesn't identify the file extensions when you import it into a typescript program. So with this declaration that red line will go away.
Did not work for me, Maybe it is because of monorepo? or me using vite?
I guess that should be the reason
@KasirBarati What really worked for me was that at the root of src folder I created a file called declaration.d.ts and added the above lines of code then stop my local server and restart it again. If this didn't work for you can try creating a file called types.d.ts instead and repeat the same approach. God luck!
|
24

there is a work around to it for example,

import logo from "../../assets/logo.png"

change this to

const logo =  require("../../assets/logo.png")

3 Comments

Will give you an error like require statement not part of an import statement
install requireJS (or was it commonJS)
require works if you are using react < 17.0.1, 17.0.1 and above use import
24

This took me about an hour so I'm going to leave the solution that worked for me.

Matt McCutchen's solution half-worked for me, but I was still facing a VSCode error. To combat this, I moved my tsconfig.json and index.d.ts to the root directory, NOT the src. Now you want your tsconfig.json to look like this:

"include": ["src", "index.d.ts"]

And for your index.d.ts, this:

declare module '*.png';
declare module '*.jpg';

(^ tweak to your typing needs)

4 Comments

"To combat this, I moved index.d.ts to the root directory, NOT the src". This was my issue too. Thanks!
I tried the solution using "require('./image/location.jpg')" as well as this solution to create index.d.ts in the root with updated includes in tsconfig.json and both worked for me.
check if you have the extension image type capitalized so put this... declare module '.png'; declare module '.PNG';
For me, this SEEMS to work at first, but sooner or later the module not found error shows up again. I think this is a bug in parcel, we should not need a workaround or pages long discussions for something as rudimentary as loading an image!
8

There should be a file called "react-app-env.d.ts" that is created when you use create-react-app. This file classes all types of image files and many more as modules that can be imported. inside the file there should be the following:

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

Comments

6

I declared multiple image types, and had to put them in separate .d.ts files to make VS Code happy:

src/types/image.jpg.d.ts:

declare module '*.jpg' {
  import { ImageSourcePropType } from 'react-native'

  const content: ImageSourcePropType

  export default content
}

src/types/image.png.d.ts:

declare module '*.png' {
  import { ImageSourcePropType } from 'react-native'

  const content: ImageSourcePropType

  export default content
}

src/types/image.svg.d.ts:

declare module '*.svg' {
  import React from 'react'
  import { SvgProps } from 'react-native-svg'

  const content: React.FC<SvgProps>

  export default content
}

No tweaks to tsconfig, etc required.

1 Comment

thx, this makes phpStorm also happy
4

I've pasted:

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

from an older project in my: react-app-env.d.ts and it worked.

In the latest versions of CRA (when TS is the chosen language), this file is automatically added to the src folder and contains the single line shown above. It is a directive to reference types from react-scripts.

5 Comments

both lines are comments?
They aren't just comments. As far as JavaScript is concerned, yes they are comments. However, the first line is a directive to eslint to ignore the linting rule for the next line. Eslint looks for these type of comments before linting the code. The second line is a way to reference types in your typescript files. See -> typescriptlang.org/docs/handbook/triple-slash-directives.html
Suppressing the error is not fixing the underlying issue and is a terrible practice!
@MichaelEakins The second line actually does clear the error rather than suppress it as you suggest. The first line is pretty much useless for the problem described in this question.
in new react typescript installation this file was included, i accidentaly delete this file. thanks a lot
4

Create a global.d.ts file inside your src directory or any rootDir

declare module "*.png" {
 export default "" as string
}

This will make use of an asset, in this case png image and also clear a vscode error

Comments

3

I test all of the replies and found the answer.

First, create a file with the name .d.ts in your route folder.

Then copy these lines into that.


declare module "*.png" {
  export default "" as string;
}
declare module "*.svg" {
  export default "" as string;
}
declare module "*.jpeg" {
  export default "" as string;
}
declare module "*.jpg" {
  export default "" as string;
}

Finally, go to tsconfig.json file in your route folder. and define new child.


{
   "include": ["src", ".d.ts"]
}

your're go to go.

Comments

3

I had this issue in my Gatsby project with TypeScript, to fix this go to your declarations.d.ts file and add this.

declare module '*.jpg'
declare module '*.png'
declare module '*.svg'
// ...

Comments

1

This is worked for me

declare module "*.png" {
const src: string
export default src
}

Comments

1

Example false positive

The image above illustrates how this error can arise falsely when you've miss quoted the path. Note I accidentally started with a double quote " and ended with a single quote '. Easy fix.

Comments

1

To address this issue, create a file named index.d.ts inside the src/Types directory. In this file, add the following declaration:

declare module '*.jpg';

This declaration allows TypeScript to recognize and import JPG image files without any type errors.

Comments

1

In simple term typescript is a statically typed language and it does comprehend these non code files. So, in order to treat non-code files as modules such as .png, .jpg etc.

  1. Create a /types directory inside /src
  2. Inside /types create a file name index.d.ts
  3. Within the file declare these
declare module "*.png";
declare module "*.jpg";

// ...rest of files extensions if any

Now, When you import a .png, etc files, it will be treated as a module.

Note: Incase of type checking, checkout the accepted answer in this thread

Comments

0

This error happens when you not included react-app-env.d.ts file in your src folder becoz you need two line of code for get rid of this error ==> <reference types="react-scripts" />

Comments

0

I fixed adding file index.d.ts in root:

Paste the following code inside of it: /// <reference types="react-scripts" />

inside tsconfig.json, add: "include": ["src", "index.d.ts"]

1 Comment

doesn't work for me
0

For those who has this issue in a monorepo

First let's clarify one thing, I assume you're using create react app or vite and still have this issue. Although it really should not matter.

How I ended up in this mess?

I just had a monorepo and I was extending from the root tsconfig.json which was a place too keep every shared configuration in my entire monorepo. So I was extending from it in each and every sub repo I had in my monorepo. OK, Here is how my directory tree looks like

|-apps
|---backend
|-----src
|-----tsconfig.json
|---frontend
|-----src
|-----tsconfig.json
|-tsconfig.json

e.x. apps/frontend/tsconfig.json

{
    "extends": "../../tsconfig.json",
    "compilerOptions": {
        /* ... */
    }
}

Solution #1

So then TS was not able to find the file definition for the images. All I did was creating a new file in the root of my monorepo, named declarations.d.ts and pasting this code inside it:

// images
declare module '*.png' {
    const src: string;
    export default src;
}
declare module '*.jpg' {
    const src: string;
    export default src;
}
declare module '*.jpeg' {
    const src: string;
    export default src;
}
declare module '*.jfif' {
    const src: string;
    export default src;
}
declare module '*.pjpeg' {
    const src: string;
    export default src;
}
declare module '*.pjp' {
    const src: string;
    export default src;
}
declare module '*.gif' {
    const src: string;
    export default src;
}
declare module '*.svg' {
    const src: string;
    export default src;
}
declare module '*.ico' {
    const src: string;
    export default src;
}
declare module '*.webp' {
    const src: string;
    export default src;
}
declare module '*.avif' {
    const src: string;
    export default src;
}

Solution #2

Though you can resolve this issue by removing that extends in your ./apps/frontend/tsconfig.json. I chose to remove the extends since it was easier to rely on Vite rather my own code. Besides this way we have less code to worry of.

Comments

0

if you have tried createing index.d.ts file in folder src, and adding declare module '*.jpg'; to it but it didn't work just rename index.d.ts to something else like export.d.ts .

Comments

0

In Blitz.js (based on Next.js) this works for me:

npx tsc-files --pretty --noEmit next-env.d.ts filenames

In package.json:

"lint-staged": {
  "*.{ts,tsx}": "tsc-files --pretty --noEmit next-env.d.ts"
}

Comments

0

Create a file custom.d.ts inside the src folder and add this lines:

declare module “.jpg” for jpg images declare module “.jpeg” for jpeg images declare module “.svg” for svg images declare module “.png” for png images

Comments

0

For react-script app, add a "{my-app-name}-env.d.ts" file in src/

Content :

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.