76

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?

John
  • 1,165
  • 2
  • 6
  • 20

6 Answers6

67

create index.d.ts file in folder src,and add this line

declare module '*.jpg';
王玉略
  • 847
  • 6
  • 7
  • 3
    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 Dec 18 '20 at 10:36
  • @Rishav I think it's shorthand declaration specific https://www.typescriptlang.org/docs/handbook/modules.html `All imports from a shorthand module will have the any type.` – llamerr Feb 08 '21 at 17:01
66

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.

Matt McCutchen
  • 22,711
  • 1
  • 39
  • 54
  • 2
    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. – John Oct 11 '18 at 13:14
  • 2
    Never mind, I think I found the problem. See the updated answer. – Matt McCutchen Oct 11 '18 at 13:20
  • 1
    Wow this is magic, thank you so much!! I spent almost the whole morning trying to figure out why it's not working :))) – John Oct 11 '18 at 13:43
  • 1
    Your Round 2 is the gift that keeps on giving. You just cleared up my issue with index.d.ts and SVGs, so thanks! – JesDaw Mar 12 '20 at 05:04
25

Create module/type

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

Change tsconfig.json

{
    "compilerOptions": {
        "typeRoots" : ["node_modules/@types", "src/types"]
    }
}
Claros
  • 83
  • 1
  • 7
mrfsb
  • 251
  • 3
  • 2
4

there is a work around to it for example,

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

change this to

const logo =  require("../../assets/logo.png")
Shubham Kakkar
  • 189
  • 1
  • 2
-1

Just add a comment to tell the compiler to ignore errors on the next line.

// @ts-ignore
import * as img from '../assets/image.jpg';
Thomas G.
  • 1,832
  • 15
  • 18
-2

I've pasted:

// eslint-disable-next-line spaced-comment
/// <reference types="react-scripts" />

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

  • 2
    both lines are comments? – Akber Iqbal Apr 29 '20 at 04:35
  • 2
    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 -> https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html – Dmase05 Sep 07 '20 at 02:40