I recently switched a webpack project written in JavaScript to TypeScript. I felt lucky that almost everything still compiled just by following webpack’s TypeScript guide, though it was a small project.

Of the things that didn’t compile: an image I was importing into my index.js (now index.ts) entry file was getting ignored.

I had two problems:

  1. TypeScript told me, more or less, that it did not understand what an image file was
  2. webpack no longer processed and copied the image to my final dist directory

The bottom of webpack’s TypeScript guide has a section called, “Importing Other Assets” that addressed my first problem. I added a file in the root directory of the project that looked like this:

declare module "*.png" {
  const content: any;
  export default content;
}

On the second problem: I spent a lot of time trying to get either file-loader or url-loader to copy the image file to my final distribution directory, as it had as a JavaScript project. I considered just moving that workflow out of webpack altogether. I could have just used a script, something like cp src/img/file.png dist/img/file.png. In the end, per this Stack Overflow discussion, I used a require statement instead of import. I changed:

import favicon from './img/favicon.png';

to

const favicon = require('./img/favicon.png');

Update on May 1, 2020:

As Karl Horky pointed out in the comments below, string would be more precise than any for the the type of content.

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

The webpack documentation also states:

Here we declare a new module for SVGs by specifying any import that ends in .svg and defining the module’s content as any. We could be more explicit about it being a url by defining the type as string. The same concept applies to other assets including CSS, SCSS, JSON and more.